Exemple #1
0
std::string transformToSHA512(std::string plainText, bool upperCase)
{
	// Crypto++ SHA512 object
	CryptoPP::SHA512 hash;

	// Use native byte instead of casting chars
	byte digest[CryptoPP::SHA512::DIGESTSIZE];

	// Do the actual calculation, require a byte value so we need a cast
	hash.CalculateDigest(digest, (const byte*)plainText.c_str(), plainText.length());

	// Crypto++ HexEncoder object
	CryptoPP::HexEncoder encoder;

	// Our output
	std::string output;

	// Drop internal hex encoder and use this, returns uppercase by default
	encoder.Attach(new CryptoPP::StringSink(output));
	encoder.Put(digest, sizeof(digest));
	encoder.MessageEnd();

	// Make sure we want uppercase
	if(upperCase)
		return output;

	// Convert to lowercase if needed
	return asLowerCaseString(output);
}
Exemple #2
0
void DigestFilePair::calculate( const fs::path file ) {
	fs::ifstream file_stream( file );
	CryptoPP::FileSource fsource( file_stream, true );
	CryptoPP::SHA512 sha;
	byte digest[sha.DigestSize()];
	byte *data = new byte[ fsource.MaxRetrievable() ];
	size_t size = fsource.Get( data, fsource.MaxRetrievable() );
	sha.CalculateDigest( digest, data, size );
	std::stringstream ss;
	for(int i = 0; i < sha.DigestSize(); i++)
		ss << std::hex << std::setw(2) << std::setfill('0') << (int) digest[i];
	delete[] data;
	_digest = ss.str();
	_file = file;
}
std::string makeHash(const std::string& input)
{
	CryptoPP::SHA512 hash;
	byte digest[ CryptoPP::SHA512::DIGESTSIZE ];

	hash.CalculateDigest( digest, (byte*) input.c_str(), input.length() );

	CryptoPP::HexEncoder encoder;
	std::string output;
	encoder.Attach( new CryptoPP::StringSink( output ) );
	encoder.Put( digest, sizeof(digest) );
	encoder.MessageEnd();

	return output;
}
Exemple #4
0
	std::string hash_sha512(std::string input)
	{
		CryptoPP::SHA512 sha;
		unsigned char* buffer = new unsigned char[sha.DigestSize()];
		unsigned char* inputbytes = new unsigned char[input.size()];
		memcpy(inputbytes, input.c_str(), input.size());
		sha.CalculateDigest(buffer, inputbytes, input.size());
		char* hashedbytes = new char[sha.DigestSize()];
		memcpy(hashedbytes, buffer, sha.DigestSize());
		std::string hashed(hashedbytes, sha.DigestSize());
		delete[] buffer;
		delete[] inputbytes;
		delete[] hashedbytes;
		return hashed;
	}
SecureBinaryData KdfRomix::DeriveKey_OneIter(SecureBinaryData const & password)
{
   static CryptoPP::SHA512 sha512;

   // Concatenate the salt/IV to the password
   SecureBinaryData saltedPassword = password + salt_; 
   
   // Prepare the lookup table
   lookupTable_.resize(memoryReqtBytes_);
   lookupTable_.fill(0);
   uint32_t const HSZ = hashOutputBytes_;
   uint8_t* frontOfLUT = lookupTable_.getPtr();
   uint8_t* nextRead  = NULL;
   uint8_t* nextWrite = NULL;

   // First hash to seed the lookup table, input is variable length anyway
   sha512.CalculateDigest(frontOfLUT, 
                          saltedPassword.getPtr(), 
                          saltedPassword.getSize());

   // Compute <sequenceCount_> consecutive hashes of the passphrase
   // Every iteration is stored in the next 64-bytes in the Lookup table
   for(uint32_t nByte=0; nByte<memoryReqtBytes_-HSZ; nByte+=HSZ)
   {
      // Compute hash of slot i, put result in slot i+1
      nextRead  = frontOfLUT + nByte;
      nextWrite = nextRead + hashOutputBytes_;
      sha512.CalculateDigest(nextWrite, nextRead, hashOutputBytes_);
   }

   // LookupTable should be complete, now start lookup sequence.
   // Start with the last hash from the previous step
   SecureBinaryData X(frontOfLUT + memoryReqtBytes_ - HSZ, HSZ);
   SecureBinaryData Y(HSZ);

   // We "integerize" a hash value by taking the last 4 bytes of
   // as a uint32_t, and take modulo sequenceCount
   uint64_t* X64ptr = (uint64_t*)(X.getPtr());
   uint64_t* Y64ptr = (uint64_t*)(Y.getPtr());
   uint64_t* V64ptr = NULL;
   uint32_t newIndex;
   uint32_t const nXorOps = HSZ/sizeof(uint64_t);

   // Pure ROMix would use sequenceCount_ for the number of lookups.
   // We divide by 2 to reduce computation time RELATIVE to the memory usage
   // This still provides suffient LUT operations, but allows us to use more
   // memory in the same amount of time (and this is the justification for
   // the scrypt algorithm -- it is basically ROMix, modified for more 
   // flexibility in controlling compute-time vs memory-usage).
   uint32_t const nLookups = sequenceCount_ / 2;
   for(uint32_t nSeq=0; nSeq<nLookups; nSeq++)
   {
      // Interpret last 4 bytes of last result (mod seqCt) as next LUT index
      newIndex = *(uint32_t*)(X.getPtr()+HSZ-4) % sequenceCount_;

      // V represents the hash result at <newIndex>
      V64ptr = (uint64_t*)(frontOfLUT + HSZ*newIndex);

      // xor X with V, and store the result in X
      for(int i=0; i<nXorOps; i++)
         *(Y64ptr+i) = *(X64ptr+i) ^ *(V64ptr+i);

      // Hash the xor'd data to get the next index for lookup
      sha512.CalculateDigest(X.getPtr(), Y.getPtr(), HSZ);
   }
   // Truncate the final result to get the final key
   lookupTable_.destroy();
   return X.getSliceCopy(0,kdfOutputBytes_);
}
Exemple #6
0
int crypto_hash(unsigned char *out,const unsigned char *in,unsigned long long inlen)
{
	CryptoPP::SHA512 sha;
	sha.CalculateDigest(out, in, inlen);
	return 0;
}
void sha512(byte* digest, string arg)
{
    CryptoPP::SHA512 hashfun;
    hashfun.CalculateDigest(digest, (byte*) arg.c_str(), arg.length());
}
Exemple #8
0
int Addr::generateDeterministic(ustring passphrase, int nonce)
{
	int nonce_old = nonce;
	int stream = 1;
	int version = 4;

	OID CURVE = secp256k1();
	AutoSeededRandomPool rng;


	ECIES<ECP>::PrivateKey privE, privS;

	ustring pubSKey;
	ustring pubEKey;

	string encoded;
	size_t len;

	byte digest2[CryptoPP::RIPEMD160::DIGESTSIZE];

	int zeros = 0;
	do
	{
		CryptoPP::SHA512 hash;
		byte digest[CryptoPP::SHA512::DIGESTSIZE];

		ustring passP = passphrase;
		passP.appendVarInt_B(nonce++);

		hash.CalculateDigest(digest, (byte*)passP.c_str(), passP.size());

		Integer x;
		x.Decode(digest, 32); //first 32 bytes
		privS.Initialize(CURVE, x);

		passP = passphrase;
		passP.appendVarInt_B(nonce++);

		hash.CalculateDigest(digest, (byte*)passP.c_str(), passP.size());

		x.Decode(digest, 32);
		privE.Initialize(CURVE, x);

		ECIES<ECP>::PublicKey pubE, pubS;
		privE.MakePublicKey(pubE);
		privS.MakePublicKey(pubS);

		encoded.clear();
		len = pubE.GetPublicElement().x.MinEncodedSize();
		pubE.GetPublicElement().x.Encode(StringSink(encoded).Ref(), len);

		len = pubE.GetPublicElement().y.MinEncodedSize();
		pubE.GetPublicElement().y.Encode(StringSink(encoded).Ref(), len);

		pubEKey.clear();
		pubEKey += 0x04;
		pubEKey.fromString(encoded);


		encoded.clear();
		len = pubS.GetPublicElement().x.MinEncodedSize();
		pubS.GetPublicElement().x.Encode(StringSink(encoded).Ref(), len);

		len = pubS.GetPublicElement().y.MinEncodedSize();
		pubS.GetPublicElement().y.Encode(StringSink(encoded).Ref(), len);

		pubSKey.clear();
		pubSKey += 0x04;
		pubSKey.fromString(encoded);


		memset(digest, 0, SHA512::DIGESTSIZE);

		ustring buffer;
		buffer += pubSKey;
		buffer += pubEKey;

		hash.CalculateDigest(digest, (byte*)buffer.c_str(), buffer.length());

		CryptoPP::RIPEMD160 hash2;
		memset(digest2, 0x00, 20);
		hash2.CalculateDigest(digest2, digest, sizeof digest);


		while (digest2[zeros] == 0x00)
			zeros++;
	} while (zeros == 0);

	encoded.clear();
	len = privE.GetPrivateExponent().MinEncodedSize();
	privE.GetPrivateExponent().Encode(StringSink(encoded).Ref(), len);

	ustring privEKey;
	privEKey.fromString(encoded);

	encoded.clear();
	len = privS.GetPrivateExponent().MinEncodedSize();
	privS.GetPrivateExponent().Encode(StringSink(encoded).Ref(), len);

	ustring privSKey;
	privSKey.fromString(encoded);

	if (!this->loadKeys(pubEKey, pubSKey, privEKey, privSKey, stream, version))
		return nonce_old;

	return nonce;
}
Exemple #9
0
bool Addr::generateRandom()
{
	int stream = 1;
	int version = 4;

	OID CURVE = secp256k1();
	AutoSeededRandomPool rng;


	ECIES<ECP>::PrivateKey privE, privS;

	ustring pubSKey;
	ustring pubEKey;

	string encoded;
	size_t len;

	byte digest2[CryptoPP::RIPEMD160::DIGESTSIZE];

	int zeros = 0;
	do
	{
		privE.Initialize(rng, CURVE);
		privS.Initialize(rng, CURVE);

		ECIES<ECP>::PublicKey pubE, pubS;
		privE.MakePublicKey(pubE);
		privS.MakePublicKey(pubS);

		encoded.clear();
		len = pubE.GetPublicElement().x.MinEncodedSize();
		pubE.GetPublicElement().x.Encode(StringSink(encoded).Ref(), len);

		len = pubE.GetPublicElement().y.MinEncodedSize();
		pubE.GetPublicElement().y.Encode(StringSink(encoded).Ref(), len);

		pubEKey.clear();
		pubEKey += 0x04;
		pubEKey.fromString(encoded);


		encoded.clear();
		len = pubS.GetPublicElement().x.MinEncodedSize();
		pubS.GetPublicElement().x.Encode(StringSink(encoded).Ref(), len);

		len = pubS.GetPublicElement().y.MinEncodedSize();
		pubS.GetPublicElement().y.Encode(StringSink(encoded).Ref(), len);

		pubSKey.clear();
		pubSKey += 0x04;
		pubSKey.fromString(encoded);


		CryptoPP::SHA512 hash;
		byte digest[CryptoPP::SHA512::DIGESTSIZE];

		ustring buffer;
		buffer += pubSKey;
		buffer += pubEKey;

		hash.CalculateDigest(digest, (byte*)buffer.c_str(), buffer.length());

		CryptoPP::RIPEMD160 hash2;
		memset(digest2, 0x00, 20);
		hash2.CalculateDigest(digest2, digest, sizeof digest);


		while (digest2[zeros] == 0x00)
			zeros++;
	} while (zeros == 0);

	encoded.clear();
	len = privE.GetPrivateExponent().MinEncodedSize();
	privE.GetPrivateExponent().Encode(StringSink(encoded).Ref(), len);

	ustring privEKey;
	privEKey.fromString(encoded);

	encoded.clear();
	len = privS.GetPrivateExponent().MinEncodedSize();
	privS.GetPrivateExponent().Encode(StringSink(encoded).Ref(), len);

	ustring privSKey;
	privSKey.fromString(encoded);

	if (!this->loadKeys(pubEKey, pubSKey, privEKey, privSKey, stream, version))
		return false;

	return true;
}
Exemple #10
0
bool PubAddr::loadAddr(ustring address)
{
	unsigned int i = 0;
	string BM = address.getString(3, i);
	if (strncmp(BM.c_str(), "BM-", 3) != 0)
	{
		i = 0;
	}

	char retu[100];
	size_t size2 = 50;
	if (b58tobin(retu, &size2, (char *)address.getRest(i).c_str()) != true)
	{
		return false; //ignoring key not valid
	}

	ustring _buffer;
	retu[size2] = 0x00;
	for (unsigned int j = 0; j < size2; j++)
		_buffer += retu[j];
	i = 0;

	unsigned int checkPos = _buffer.length() - 4;

	if (checkPos < (unsigned int)0)
		return false;

	ustring buffer = _buffer.getUstring(checkPos, i);

	byte checksum[4];
	memcpy(checksum, _buffer.getUstring(4, checkPos).c_str(), sizeof checksum);

	CryptoPP::SHA512 hash;
	byte digest[CryptoPP::SHA512::DIGESTSIZE];
	byte digest2[CryptoPP::SHA512::DIGESTSIZE];
	hash.CalculateDigest(digest, (byte*)buffer.c_str(), buffer.length());
	hash.CalculateDigest(digest2, digest, sizeof digest);

	if (memcmp(digest2, checksum, sizeof checksum)!=0)
	{
		return false; //ignoring key not valid
	}

	i = 0;

	std::unique_lock<std::shared_timed_mutex> mlock(this->mutex_);
	this->address = address;

	int tmp_vers = (int)buffer.getVarInt_B(i);
	int tmp_stream = (int)buffer.getVarInt_B(i);

	ustring tmp_ripe = buffer.getRest(i);

	if (tmp_ripe.length() > 20)
		return false; //too long

	if (tmp_ripe.length() < 4)
		return false; //too short

	this->version = tmp_vers;
	this->stream = tmp_stream;

	while (tmp_ripe.length() != 20) //todo add function prepend
	{
		ustring tmp2;
		tmp2.appendInt8(0);
		tmp2+=tmp_ripe;
		tmp_ripe = tmp2;
	}

	this->ripe.clear();
	this->ripe = tmp_ripe;

	buffer.clear();
	buffer.appendVarInt_B(this->version);
	buffer.appendVarInt_B(this->stream);
	buffer += this->ripe;

	hash.CalculateDigest(digest, (byte*)buffer.c_str(), buffer.length());
	hash.CalculateDigest(digest2, digest, sizeof digest);

	this->tagE.clear();
	this->tagE.append(digest2, 32);
	this->tag.clear();
	this->tag.append(&(digest2[32]), 32);

	this->empty = true;
	mlock.unlock();
	return true;
}
Exemple #11
0
ustring PubAddr::buildAddressFromKeys(ustring Skey, ustring Ekey, int stream, int version)
{
	CryptoPP::SHA512 hash;
	byte digest[CryptoPP::SHA512::DIGESTSIZE];
	byte digest1[CryptoPP::SHA512::DIGESTSIZE];

	ustring buffer;
	if (Skey.size() == 64)
	{
		ustring tmp = Skey;
		Skey.clear();
		Skey += 0x04;
		Skey += tmp;
	}
	if (Ekey.size() == 64)
	{
		ustring tmp = Ekey;
		Ekey.clear();
		Ekey += 0x04;
		Ekey += tmp;
	}
	buffer += Skey;
	buffer += Ekey;

	hash.CalculateDigest(digest, (byte*)buffer.c_str(), buffer.length());

	CryptoPP::RIPEMD160 hash2;
	byte digest2[CryptoPP::RIPEMD160::DIGESTSIZE];
	hash2.CalculateDigest(digest2, digest, sizeof digest);

	ustring ripe;
	int i = 0;
	while (digest2[i] == 0x00)
		i++;

	while (i < sizeof digest2)
	{
		ripe += digest2[i];
		i++;
	}

	ustring tmp;
	tmp.appendVarInt_B(version);
	tmp.appendVarInt_B(stream);
	tmp += ripe;

	//generate checksum
	hash.CalculateDigest(digest, (byte*)tmp.c_str(), tmp.length());
	hash.CalculateDigest(digest1, digest, sizeof digest);

	tmp += digest1[0];
	tmp += digest1[1];
	tmp += digest1[2];
	tmp += digest1[3];

	//convert to base58
	char * ret = new char[256];
	size_t size = 256;
	if (!b58enc(ret, &size, tmp.c_str(), tmp.size()))
	{
		delete[] ret;
		throw runtime_error("cannot encode base58");
	}
	ustring addr;
	addr.fromString(string("BM-"));

	addr.append((unsigned char*)ret, size-1);
	delete[] ret;
	return addr;
}
Exemple #12
0
ustring PubAddr::encode(ustring pubKA, ustring privKB , ustring pubKB ,ustring plain)
{
	OID CURVE = secp256k1();
	AutoSeededRandomPool rng;

	ECDH < ECP >::Domain dhA(CURVE), dhB(CURVE);
	SecByteBlock privB(privKB.c_str(), dhA.PrivateKeyLength());
	SecByteBlock pubA(pubKA.c_str(), dhB.PublicKeyLength());

	if (dhA.AgreedValueLength() != dhB.AgreedValueLength())
		throw runtime_error("Shared shared size mismatch");

	SecByteBlock sharedA(dhA.AgreedValueLength()), sharedB(dhB.AgreedValueLength());

	if (!dhA.Agree(sharedA, privB, pubA))
		throw runtime_error("Failed to reach shared secret (A)");


	Integer ssa, ssb;

	ssa.Decode(sharedA.BytePtr(), sharedA.SizeInBytes());

	uint8_t H[CryptoPP::SHA512::DIGESTSIZE];
	CryptoPP::SHA512 hash;

	hash.CalculateDigest(H, sharedA.BytePtr(), sharedA.SizeInBytes());



	AutoSeededRandomPool prng;

	byte key[32];

	memcpy(key, H, sizeof(key));

	byte Hkey[32];

	memcpy(Hkey, &(H[32]), sizeof(Hkey));

	byte iv[16];
	prng.GenerateBlock(iv, sizeof(iv));

	string SPlain = plain.toString(), encoded;

	try
	{
		CBC_Mode< AES >::Encryption e;
		e.SetKeyWithIV(key, sizeof(key), iv);

		// The StreamTransformationFilter removes
		//  padding as required.
		StringSource s(SPlain, true,
			new StreamTransformationFilter(e,
				new StringSink(encoded)
				) // StreamTransformationFilter
			); // StringSource
	}
	catch (const CryptoPP::Exception& e)
	{
		throw runtime_error(e.what());
	}



	ustring result;
	result.append(iv, 16);
	result.appendInt16(714);
	result.appendInt16(32);
	result.append(pubKB.c_str() + 1, 32);
	result.appendInt16(32);
	result.append(pubKB.c_str() + 33, 32);
	result.fromString(encoded);



	string HMacPlain;

	HMacPlain += result.toString();

	string mac;

	try
	{
		HMAC<SHA256> hmac(Hkey, 32);
		StringSource s(HMacPlain, true,
			new HashFilter(hmac,
				new StringSink(mac)
				)
			);
	}
	catch (const CryptoPP::Exception& e)
	{
		throw runtime_error(e.what());
	}

	result.fromString(mac);

	return result;
}
Exemple #13
0
ustring PubAddr::decode(ustring data, ustring privK)
{
	unsigned int p = 0;

	ustring IV = data.getUstring(16, p);
	unsigned int curveType = data.getInt16(p);
	unsigned int Xlen = data.getInt16(p);
	ustring X = data.getUstring(Xlen, p);
	unsigned int Ylen = data.getInt16(p);
	ustring Y = data.getUstring(Ylen, p);
	ustring cipherText = data.getUstring(data.size() - (p + 32), p);
	ustring MAC = data.getUstring(32, p);

	ustring pubK;
	pubK += 0x04;
	pubK += X;
	pubK += Y;


	OID CURVE = secp256k1();
	AutoSeededRandomPool rng;

	ECDH < ECP >::Domain dhA(CURVE), dhB(CURVE);
	SecByteBlock privA(privK.c_str(), dhA.PrivateKeyLength());
	SecByteBlock pubB(pubK.c_str(), dhB.PublicKeyLength());

	if (dhA.AgreedValueLength() != dhB.AgreedValueLength())
	{
		throw runtime_error("Shared shared size mismatch");
	}
	SecByteBlock sharedA(dhA.AgreedValueLength()), sharedB(dhB.AgreedValueLength());

	if (!dhA.Agree(sharedA, privA, pubB))
		throw runtime_error("Failed to reach shared secret (A)");


	Integer ssa, ssb;

	ssa.Decode(sharedA.BytePtr(), sharedA.SizeInBytes());

	uint8_t H[CryptoPP::SHA512::DIGESTSIZE];
	CryptoPP::SHA512 hash;

	hash.CalculateDigest(H, sharedA.BytePtr(), sharedA.SizeInBytes());



	AutoSeededRandomPool prng;

	byte key[32];

	memcpy(key, H, sizeof(key));

	byte Hkey[32];

	memcpy(Hkey, &(H[32]), sizeof(Hkey));

	byte iv[16];

	memcpy(iv, IV.c_str(), IV.size());

	string cipher = cipherText.toString(), encoded, recovered;

	string HMacPlain;

	p = 0;
	HMacPlain += data.getString(data.size()-32,p);

	string mac;

	try
	{
		HMAC<SHA256> hmac(Hkey, 32);
		StringSource s(HMacPlain, true,
			new HashFilter(hmac,
				new StringSink(mac)
				)
			);
	}
	catch (const CryptoPP::Exception& e)
	{
		throw runtime_error(e.what());
	}

	if (mac != MAC.toString())
		throw runtime_error("mac doesnt match");

	try
	{
		CBC_Mode< AES >::Decryption d;
		d.SetKeyWithIV(key, sizeof(key), iv);

		// The StreamTransformationFilter removes
		//  padding as required.
		StringSource s(cipher, true,
			new StreamTransformationFilter(d,
				new StringSink(recovered)
				) // StreamTransformationFilter
			); // StringSource
	}
	catch (const CryptoPP::Exception& e)
	{
		throw runtime_error(e.what());
	}

	ustring result;
	result.fromString(recovered);
	return result;
}
bool CCryptoModulus::InitCrypto(BYTE *temp, DWORD length)
{
    int hashid = 0;
    BYTE digest[2048];


    memset(digest, 0, sizeof(digest));


    if (length >= 10)
    {
        hashid = temp[4] ^ (temp[3] | (temp[1] ^ temp[0]) < temp[2] % 3);
    }
    else
    {
        hashid = temp[0];
    }


    hashid = (hashid % 11) - 1;


    switch (hashid)
    {
        case 0:
        {
            CryptoPP::SHA256 hash;
            hash.Update(temp, length);
            hash.Final(digest);


            this->m_algorithm = digest[0] % 10;
            this->InitCrypto(this->m_algorithm, digest, 32);
        }
        break;


        case 2:
        {
            CryptoPP::SHA512 hash;
            hash.Update(temp, length);
            hash.Final(digest);


            this->m_algorithm = digest[1] % 10;
            this->InitCrypto(this->m_algorithm, digest, 64);
        }
        break;
        
        case 3:
        {
            CryptoPP::SHA384 hash;
            hash.Update(temp, length);
            hash.Final(digest);


            this->m_algorithm = digest[2] % 10;
            this->InitCrypto(this->m_algorithm, digest, 48);
        }
        break;


        case 4:
        {
            CryptoPP::Weak1::MD4 hash;
            hash.Update(temp, length);
            hash.Final(digest);


            this->m_algorithm = digest[3] % 10;
            this->InitCrypto(this->m_algorithm, digest, 16);
        }
        break;


        case 5:
        {
            CryptoPP::Weak1::MD5 hash;
            hash.Update(temp, length);
            hash.Final(digest);


            this->m_algorithm = digest[4] % 10;
            this->InitCrypto(this->m_algorithm, digest, 16);
        }
        break;


        case 6:
        {
            CryptoPP::RIPEMD160 hash;
            hash.Update(temp, length);
            hash.Final(digest);


            this->m_algorithm = digest[5] % 10;
            this->InitCrypto(this->m_algorithm, digest, 20);
        }
        break;


        case 7:
        {
            CryptoPP::RIPEMD320 hash;
            hash.Update(temp, length);
            hash.Final(digest);


            this->m_algorithm = digest[6] % 10;
            this->InitCrypto(this->m_algorithm, digest, 40);
        }
        break;


        case 8:
        {
            CryptoPP::RIPEMD128 hash;
            hash.Update(temp, length);
            hash.Final(digest);


            this->m_algorithm = digest[7] % 10;
            this->InitCrypto(this->m_algorithm, digest, 16);
        }
        break;


        case 9:
        {
            CryptoPP::RIPEMD256 hash;
            hash.Update(temp, length);
            hash.Final(digest);


            this->m_algorithm = digest[8] % 10;
            this->InitCrypto(this->m_algorithm, digest, 32);
        }
        break;


        default:
        {
            CryptoPP::Weak1::MD5 hash;
            hash.Update(temp, length);
            hash.Final(digest);


            this->m_algorithm = digest[9] % 10;
            this->InitCrypto(this->m_algorithm, digest, 16);
        }
        break;
    }


    return true;
}