]> git.sesse.net Git - freerainbowtables/blobdiff - Client Applications/rcracki_mt/ChainWalkContext.cpp
(C)
[freerainbowtables] / Client Applications / rcracki_mt / ChainWalkContext.cpp
index 01a46e023e1d81f81019b8c28fba03480f8e4ba5..4fdcf6e2d08811264d1d2ce58648fa4fb016b15d 100644 (file)
-/*
- * rcracki_mt is a multithreaded implementation and fork of the original 
- * RainbowCrack
- *
- * Copyright (C) Zhu Shuanglei <shuanglei@hotmail.com>
- * Copyright Martin Westergaard Jørgensen <martinwj2005@gmail.com>
- * Copyright 2009, 2010 Daniël Niggebrugge <niggebrugge@fox-it.com>
- * Copyright 2009, 2010 James Nobis <frt@quelrod.net>
- * Copyright 2010 Yngve AAdlandsvik
- *
- * This file is part of rcracki_mt.
- *
- * rcracki_mt is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 2 of the License, or
- * (at your option) any later version.
- *
- * rcracki_mt is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with rcracki_mt.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#if defined(_WIN32) && !defined(__GNUC__)
-       #pragma warning(disable : 4786 4267 4018)
-#endif
-
-#include "ChainWalkContext.h"
-
-#include <ctype.h>
-
-//////////////////////////////////////////////////////////////////////
-
-string CChainWalkContext::m_sHashRoutineName;
-HASHROUTINE CChainWalkContext::m_pHashRoutine;
-int CChainWalkContext::m_nHashLen;
-int CChainWalkContext::m_nPlainLenMinTotal = 0;
-int CChainWalkContext::m_nPlainLenMaxTotal = 0;
-int CChainWalkContext::m_nHybridCharset = 0;
-bool CChainWalkContext::isOldRtFormat = false;
-bool CChainWalkContext::isRti2RtFormat = false;
-vector<stCharset> CChainWalkContext::m_vCharset;
-uint64 CChainWalkContext::m_nPlainSpaceUpToX[MAX_PLAIN_LEN + 1];
-uint64 CChainWalkContext::m_nPlainSpaceTotal;
-unsigned char CChainWalkContext::m_Salt[MAX_SALT_LEN];
-int CChainWalkContext::m_nSaltLen = 0;
-int CChainWalkContext::m_nRainbowTableIndex;
-uint64 CChainWalkContext::m_nReduceOffset;
-
-//////////////////////////////////////////////////////////////////////
-
-CChainWalkContext::CChainWalkContext()
-{
-}
-
-CChainWalkContext::~CChainWalkContext()
-{
-}
-
-bool CChainWalkContext::LoadCharset(string sName)
-{
-       m_vCharset.clear();
-       if (sName == "byte")
-       {
-               stCharset tCharset;
-               int i;
-               for (i = 0x00; i <= 0xff; i++)
-                       tCharset.m_PlainCharset[i] = (unsigned char) i;
-               tCharset.m_nPlainCharsetLen = 256;
-               tCharset.m_sPlainCharsetName = sName;
-               tCharset.m_sPlainCharsetContent = "0x00, 0x01, ... 0xff";
-               m_vCharset.push_back(tCharset);
-               return true;
-       }
-       if(sName.substr(0, 6) == "hybrid") // Hybrid charset consisting of 2 charsets
-               m_nHybridCharset = 1;           
-       else
-               m_nHybridCharset = 0;
-       
-       bool readCharset = false;
-       vector<string> vLine;
-
-       if ( ReadLinesFromFile("charset.txt", vLine) )
-               readCharset = true;
-       else if ( ReadLinesFromFile(GetApplicationPath() + "charset.txt", vLine) )
-               readCharset = true;
-
-       if (readCharset)
-       {
-               UINT4 i;
-               for (i = 0; i < vLine.size(); i++)
-               {
-                       // Filter comment
-                       if (vLine[i][0] == '#')
-                               continue;
-
-                       vector<string> vPart;
-                       if (SeperateString(vLine[i], "=", vPart))
-                       {
-                               // sCharsetName
-                               string sCharsetName = TrimString(vPart[0]);
-                               if (sCharsetName == "")
-                                       continue;
-                                                               
-                               // sCharsetName charset check
-                               bool fCharsetNameCheckPass = true;
-                               UINT4 j;
-                               for (j = 0; j < sCharsetName.size(); j++)
-                               {
-                                       if (   !isalpha(sCharsetName[j])
-                                               && !isdigit(sCharsetName[j])
-                                               && (sCharsetName[j] != '-'))
-                                       {
-                                               fCharsetNameCheckPass = false;
-                                               break;
-                                       }
-                               }
-                               if (!fCharsetNameCheckPass)
-                               {
-                                       printf("invalid charset name %s in charset configuration file\n", sCharsetName.c_str());
-                                       continue;
-                               }
-
-                               // sCharsetContent
-                               string sCharsetContent = TrimString(vPart[1]);
-                               if (sCharsetContent == "" || sCharsetContent == "[]")
-                                       continue;
-                               if (sCharsetContent[0] != '[' || sCharsetContent[sCharsetContent.size() - 1] != ']')
-                               {
-                                       printf("invalid charset content %s in charset configuration file\n", sCharsetContent.c_str());
-                                       continue;
-                               }
-                               sCharsetContent = sCharsetContent.substr(1, sCharsetContent.size() - 2);
-                               if (sCharsetContent.size() > 256)
-                               {
-                                       printf("charset content %s too long\n", sCharsetContent.c_str());
-                                       continue;
-                               }
-
-                               //printf("%s = [%s]\n", sCharsetName.c_str(), sCharsetContent.c_str());
-
-                               // Is it the wanted charset?
-                               if(m_nHybridCharset == 1)
-                               {
-                                       vector<tCharset> vCharsets;
-                                       GetHybridCharsets(sName, vCharsets);
-                                       if(sCharsetName == vCharsets[m_vCharset.size()].sName)
-                                       {
-                                               stCharset tCharset;
-                                               tCharset.m_nPlainCharsetLen = sCharsetContent.size();                                                   
-                                               memcpy(tCharset.m_PlainCharset, sCharsetContent.c_str(), tCharset.m_nPlainCharsetLen);
-                                               tCharset.m_sPlainCharsetName = sCharsetName;
-                                               tCharset.m_sPlainCharsetContent = sCharsetContent;      
-                                               tCharset.m_nPlainLenMin = vCharsets[m_vCharset.size()].nPlainLenMin;
-                                               tCharset.m_nPlainLenMax = vCharsets[m_vCharset.size()].nPlainLenMax;
-                                               m_vCharset.push_back(tCharset);
-                                               if(vCharsets.size() == m_vCharset.size())
-                                                       return true;
-                                               i = 0; // Start the lookup over again for the next charset
-                                       }                                               
-                               }
-                               else if (sCharsetName == sName)
-                               {
-                                       stCharset tCharset;
-                                       tCharset.m_nPlainCharsetLen = sCharsetContent.size();                                                   
-                                       memcpy(tCharset.m_PlainCharset, sCharsetContent.c_str(), tCharset.m_nPlainCharsetLen);
-                                       tCharset.m_sPlainCharsetName = sCharsetName;
-                                       tCharset.m_sPlainCharsetContent = sCharsetContent;                                                      
-                                       m_vCharset.push_back(tCharset);
-                                       return true;
-                               }
-                       }
-               }
-               printf("charset %s not found in charset.txt\n", sName.c_str());
-       }
-       else
-               printf("can't open charset configuration file\n");
-       return false;
-}
-
-//////////////////////////////////////////////////////////////////////
-
-bool CChainWalkContext::SetHashRoutine(string sHashRoutineName)
-{
-       CHashRoutine hr;
-       hr.GetHashRoutine(sHashRoutineName, m_pHashRoutine, m_nHashLen);
-       if (m_pHashRoutine != NULL)
-       {
-               m_sHashRoutineName = sHashRoutineName;
-               return true;
-       }
-       else
-               return false;
-}
-
-bool CChainWalkContext::SetPlainCharset(string sCharsetName, int nPlainLenMin, int nPlainLenMax)
-{
-       // m_PlainCharset, m_nPlainCharsetLen, m_sPlainCharsetName, m_sPlainCharsetContent
-       if (!LoadCharset(sCharsetName))
-               return false;
-
-       if(m_vCharset.size() == 1) // Not hybrid charset
-       {
-               // m_nPlainLenMin, m_nPlainLenMax
-               if (nPlainLenMin < 1 || nPlainLenMax > MAX_PLAIN_LEN || nPlainLenMin > nPlainLenMax)
-               {
-                       printf("invalid plaintext length range: %d - %d\n", nPlainLenMin, nPlainLenMax);
-                       return false;
-               }
-               m_vCharset[0].m_nPlainLenMin = nPlainLenMin;
-               m_vCharset[0].m_nPlainLenMax = nPlainLenMax;
-       }
-       // m_nPlainSpaceUpToX
-       m_nPlainSpaceUpToX[0] = 0;
-       m_nPlainLenMaxTotal = 0;
-       m_nPlainLenMinTotal = 0;
-       uint64 nTemp = 1;
-       UINT4 j, k = 1;
-       for(j = 0; j < m_vCharset.size(); j++)
-       {
-               int i;
-               m_nPlainLenMaxTotal += m_vCharset[j].m_nPlainLenMax;
-               m_nPlainLenMinTotal += m_vCharset[j].m_nPlainLenMin;
-               for (i = 1; i <= m_vCharset[j].m_nPlainLenMax; i++)
-               {                       
-                       nTemp *= m_vCharset[j].m_nPlainCharsetLen;
-                       if (i < m_vCharset[j].m_nPlainLenMin)
-                               m_nPlainSpaceUpToX[k] = 0;
-                       else
-                               m_nPlainSpaceUpToX[k] = m_nPlainSpaceUpToX[k - 1] + nTemp;
-                       k++;
-               }               
-       }
-       // m_nPlainSpaceTotal
-       m_nPlainSpaceTotal = m_nPlainSpaceUpToX[m_nPlainLenMaxTotal];
-
-       return true;
-}
-
-bool CChainWalkContext::SetRainbowTableIndex(int nRainbowTableIndex)
-{
-       if (nRainbowTableIndex < 0)
-               return false;
-       m_nRainbowTableIndex = nRainbowTableIndex;
-       m_nReduceOffset = 65536 * nRainbowTableIndex;
-
-       return true;
-}
-
-bool CChainWalkContext::SetSalt(unsigned char *Salt, int nSaltLength)
-{
-       memcpy(&m_Salt[0], Salt, nSaltLength);
-       
-       m_nSaltLen = nSaltLength;
-//     m_sSalt = sSalt;
-       return true;
-}
-
-bool CChainWalkContext::SetupWithPathName(string sPathName, int& nRainbowChainLen, int& nRainbowChainCount)
-{
-       // something like lm_alpha#1-7_0_100x16_test.rt
-
-#ifdef _WIN32
-       string::size_type nIndex = sPathName.find_last_of('\\');
-#else
-       string::size_type nIndex = sPathName.find_last_of('/');
-#endif
-       if (nIndex != string::npos)
-               sPathName = sPathName.substr(nIndex + 1);
-
-       if (sPathName.size() < 3)
-       {
-               printf("%s is not a rainbow table\n", sPathName.c_str());
-               return false;
-       }
-       if (sPathName.substr(sPathName.size() - 5) == ".rti2")
-       {
-               isRti2RtFormat = true;
-       }
-       else if (sPathName.substr(sPathName.size() - 4) == ".rti")
-       {
-               isOldRtFormat = false;
-       }
-       else if (sPathName.substr(sPathName.size() - 3) == ".rt")
-       {
-               isOldRtFormat = true;
-       }
-       else
-       {
-               printf("%s is not a rainbow table\n", sPathName.c_str());
-               return false;
-       }
-
-       // Parse
-       vector<string> vPart;
-       if (!SeperateString(sPathName, "___x_", vPart))
-       {
-               printf("filename %s not identified\n", sPathName.c_str());
-               return false;
-       }
-
-       string sHashRoutineName   = vPart[0];
-       int nRainbowTableIndex    = atoi(vPart[2].c_str());
-       nRainbowChainLen          = atoi(vPart[3].c_str());
-       nRainbowChainCount        = atoi(vPart[4].c_str());
-
-       // Parse charset definition
-       string sCharsetDefinition = vPart[1];
-       string sCharsetName;
-       int nPlainLenMin = 0, nPlainLenMax = 0;         
-
-//     printf("Charset: %s", sCharsetDefinition.c_str());
-       
-       if(sCharsetDefinition.substr(0, 6) == "hybrid") // Hybrid table
-       {
-               sCharsetName = sCharsetDefinition;
-       }
-       else
-       {
-               if ( sCharsetDefinition.find('#') == string::npos )             // For backward compatibility, "#1-7" is implied
-               {                       
-                       sCharsetName = sCharsetDefinition;
-                       nPlainLenMin = 1;
-                       nPlainLenMax = 7;
-               }
-               else
-               {
-                       vector<string> vCharsetDefinitionPart;
-                       if (!SeperateString(sCharsetDefinition, "#-", vCharsetDefinitionPart))
-                       {
-                               printf("filename %s not identified\n", sPathName.c_str());
-                               return false;   
-                       }
-                       else
-                       {
-                               sCharsetName = vCharsetDefinitionPart[0];
-                               nPlainLenMin = atoi(vCharsetDefinitionPart[1].c_str());
-                               nPlainLenMax = atoi(vCharsetDefinitionPart[2].c_str());
-                       }
-               }
-       }
-       // Setup
-       if (!SetHashRoutine(sHashRoutineName))
-       {
-               printf("hash routine %s not supported\n", sHashRoutineName.c_str());
-               return false;
-       }
-       if (!SetPlainCharset(sCharsetName, nPlainLenMin, nPlainLenMax))
-               return false;
-       if (!SetRainbowTableIndex(nRainbowTableIndex))
-       {
-               printf("invalid rainbow table index %d\n", nRainbowTableIndex);
-               return false;
-       }
-       m_nPlainSpaceTotal = m_nPlainSpaceUpToX[m_nPlainLenMaxTotal];
-       return true;
-}
-
-string CChainWalkContext::GetHashRoutineName()
-{
-       return m_sHashRoutineName;
-}
-
-int CChainWalkContext::GetHashLen()
-{
-       return m_nHashLen;
-}
-
-string CChainWalkContext::GetPlainCharsetName()
-{
-       return m_vCharset[0].m_sPlainCharsetName;
-}
-
-string CChainWalkContext::GetPlainCharsetContent()
-{
-       return m_vCharset[0].m_sPlainCharsetContent;
-}
-
-int CChainWalkContext::GetPlainLenMin()
-{
-       return m_vCharset[0].m_nPlainLenMin;
-}
-
-int CChainWalkContext::GetPlainLenMax()
-{
-       return m_vCharset[0].m_nPlainLenMax;
-}
-
-uint64 CChainWalkContext::GetPlainSpaceTotal()
-{
-       return m_nPlainSpaceTotal;
-}
-
-int CChainWalkContext::GetRainbowTableIndex()
-{
-       return m_nRainbowTableIndex;
-}
-
-void CChainWalkContext::Dump()
-{
-       printf("hash routine: %s\n", m_sHashRoutineName.c_str());
-       printf("hash length: %d\n", m_nHashLen);
-
-       printf("plain charset: ");
-       unsigned int i;
-       for (i = 0; i < m_vCharset[0].m_nPlainCharsetLen; i++)
-       {
-               if (isprint(m_vCharset[0].m_PlainCharset[i]))
-                       printf("%c", m_vCharset[0].m_PlainCharset[i]);
-               else
-                       printf("?");
-       }
-       printf("\n");
-
-       printf("plain charset in hex: ");
-       for (i = 0; i < m_vCharset[0].m_nPlainCharsetLen; i++)
-               printf("%02x ", m_vCharset[0].m_PlainCharset[i]);
-       printf("\n");
-
-       printf("plain length range: %d - %d\n", m_vCharset[0].m_nPlainLenMin, m_vCharset[0].m_nPlainLenMax);
-       printf("plain charset name: %s\n", m_vCharset[0].m_sPlainCharsetName.c_str());
-       //printf("plain charset content: %s\n", m_sPlainCharsetContent.c_str());
-       //for (i = 0; i <= m_nPlainLenMax; i++)
-       //      printf("plain space up to %d: %s\n", i, uint64tostr(m_nPlainSpaceUpToX[i]).c_str());
-       printf("plain space total: %s\n", uint64tostr(m_nPlainSpaceTotal).c_str());
-
-       printf("rainbow table index: %d\n", m_nRainbowTableIndex);
-       printf("reduce offset: %s\n", uint64tostr(m_nReduceOffset).c_str());
-       printf("\n");
-}
-
-void CChainWalkContext::SetIndex(uint64 nIndex)
-{
-       m_nIndex = nIndex;
-}
-
-void CChainWalkContext::SetHash(unsigned char* pHash)
-{
-       memcpy(m_Hash, pHash, m_nHashLen);
-}
-
-void CChainWalkContext::IndexToPlain()
-{
-       int i;
-       m_nPlainLen = 0;
-///*
-       for (i = m_nPlainLenMaxTotal - 1; i >= m_nPlainLenMinTotal - 1; i--)
-       {
-               if (m_nIndex >= m_nPlainSpaceUpToX[i])
-               {
-                       m_nPlainLen = i + 1;
-                       break;
-               }
-       }
-
-       // this is an optimized version of the above
-/*
-       for (i = m_nPlainLenMaxTotal - 1; i >= m_nPlainLenMinTotal - 1
-               && m_nIndex < m_nPlainSpaceUpToX[i]; i--)
-       { }
-       
-       m_nPlainLen = i + 1;
-*/
-
-       if(m_nPlainLen == 0)
-               m_nPlainLen = m_nPlainLenMinTotal;
-       uint64 nIndexOfX = m_nIndex - m_nPlainSpaceUpToX[m_nPlainLen - 1];
-
-// this is the generic code for non x86/x86_64 platforms
-#if !defined(_M_X64) && !defined(_M_IX86) && !defined(__i386__) && !defined(__x86_64__)
-       
-       // generic version (slow for non 64-bit platforms and gcc < 4.5.x)
-       for (i = m_nPlainLen - 1; i >= 0; i--)
-       {
-               int nCharsetLen = 0;
-               for(UINT4 j = 0; j < m_vCharset.size(); j++)
-               {
-                       nCharsetLen += m_vCharset[j].m_nPlainLenMax;
-                       if(i < nCharsetLen) // We found the correct charset
-                       {
-                               m_Plain[i] = m_vCharset[j].m_PlainCharset[nIndexOfX % m_vCharset[j].m_nPlainCharsetLen];
-                               nIndexOfX /= m_vCharset[j].m_nPlainCharsetLen;
-                               break;
-                       }
-               }
-       }
-
-#elif defined(_M_X64) || defined(_M_IX86) || defined(__i386__) || defined(__x86_64__)
-
-       // Fast ia32 version
-       for (i = m_nPlainLen - 1; i >= 0; i--)
-       {
-               // 0x100000000 = 2^32
-#ifdef _M_IX86
-               if (nIndexOfX < 0x100000000I64)
-                       break;
-#else
-               if (nIndexOfX < 0x100000000llu)
-                       break;
-#endif
-
-               int nCharsetLen = 0;
-               for(UINT4 j = 0; j < m_vCharset.size(); j++)
-               {
-                       nCharsetLen += m_vCharset[j].m_nPlainLenMax;
-                       if(i < nCharsetLen) // We found the correct charset
-                       {
-                               m_Plain[i] = m_vCharset[j].m_PlainCharset[nIndexOfX % m_vCharset[j].m_nPlainCharsetLen];
-                               nIndexOfX /= m_vCharset[j].m_nPlainCharsetLen;
-                               break;
-                       }
-               }
-       }
-
-       UINT4 nIndexOfX32 = (UINT4)nIndexOfX;
-       for (; i >= 0; i--)
-       {
-               int nCharsetLen = 0;
-               for(UINT4 j = 0; j < m_vCharset.size(); j++)
-               {
-                       nCharsetLen += m_vCharset[j].m_nPlainLenMax;
-                       if(i < nCharsetLen) // We found the correct charset
-                       {
-
-//             m_Plain[i] = m_vCharset[j].m_PlainCharset[nIndexOfX32 % m_vCharset[j].m_nPlainCharsetLen];
-//             nIndexOfX32 /= m_vCharset[j].m_nPlainCharsetLen;
-
-
-//     moving nPlainCharsetLen into the asm body and avoiding the extra temp
-//     variable results in a performance gain
-//                             unsigned int nPlainCharsetLen = m_vCharset[j].m_nPlainCharsetLen;
-                               unsigned int nTemp;
-
-#if defined(_WIN32) && !defined(__GNUC__)
-
-               // VC++ still needs this
-               unsigned int nPlainCharsetLen = m_vCharset[j].m_nPlainCharsetLen;
-
-               __asm
-               {
-                       mov eax, nIndexOfX32
-                       xor edx, edx
-                       div nPlainCharsetLen
-                       mov nIndexOfX32, eax
-                       mov nTemp, edx
-               }
-               m_Plain[i] = m_vCharset[j].m_PlainCharset[nTemp];
-#else
-               __asm__ __volatile__ (  "mov %2, %%eax;"
-                                                               "xor %%edx, %%edx;"
-                                                               "divl %3;"
-                                                               "mov %%eax, %0;"
-                                                               "mov %%edx, %1;"
-                                                               : "=m"(nIndexOfX32), "=m"(nTemp)
-                                                               : "m"(nIndexOfX32), "m"(m_vCharset[j].m_nPlainCharsetLen)
-                                                               : "%eax", "%edx"
-                                                        );
-               m_Plain[i] = m_vCharset[j].m_PlainCharset[nTemp];
-#endif
-               break;
-                       }
-               }
-       }
-#endif
-}
-
-void CChainWalkContext::PlainToHash()
-{      
-       m_pHashRoutine(m_Plain, m_nPlainLen, m_Hash);
-}
-
-void CChainWalkContext::HashToIndex(int nPos)
-{
-       m_nIndex = (*(uint64*)m_Hash + m_nReduceOffset + nPos) % m_nPlainSpaceTotal;
-}
-
-uint64 CChainWalkContext::GetIndex()
-{
-       return m_nIndex;
-}
-const uint64 *CChainWalkContext::GetIndexPtr()
-{
-       return &m_nIndex;
-}
-
-string CChainWalkContext::GetPlain()
-{
-       string sRet;
-       int i;
-       for (i = 0; i < m_nPlainLen; i++)
-       {
-               char c = m_Plain[i];
-               sRet += c;
-       }
-       
-       return sRet;
-}
-
-string CChainWalkContext::GetBinary()
-{
-       return HexToStr(m_Plain, m_nPlainLen);
-}
-
-string CChainWalkContext::GetHash()
-{
-       return HexToStr(m_Hash, m_nHashLen);
-}
-
-bool CChainWalkContext::CheckHash(unsigned char* pHash)
-{
-       if (memcmp(m_Hash, pHash, m_nHashLen) == 0)
-               return true;
-
-       return false;
-}
-
-bool CChainWalkContext::isOldFormat()
-{
-       return isOldRtFormat;
-}
-
-bool CChainWalkContext::isRti2Format()
-{
-       return isRti2RtFormat;
-}
+/*\r
+ * rcracki_mt is a multithreaded implementation and fork of the original \r
+ * RainbowCrack\r
+ *\r
+ * Copyright (C) Zhu Shuanglei <shuanglei@hotmail.com>\r
+ * Copyright Martin Westergaard Jørgensen <martinwj2005@gmail.com>\r
+ * Copyright 2009, 2010 Daniël Niggebrugge <niggebrugge@fox-it.com>\r
+ * Copyright 2009, 2010, 2011 James Nobis <frt@quelrod.net>\r
+ * Copyright 2010 Yngve AAdlandsvik\r
+ *\r
+ * This file is part of rcracki_mt.\r
+ *\r
+ * rcracki_mt is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 2 of the License, or\r
+ * (at your option) any later version.\r
+ *\r
+ * rcracki_mt is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with rcracki_mt.  If not, see <http://www.gnu.org/licenses/>.\r
+ */\r
+\r
+#if defined(_WIN32) && !defined(__GNUC__)\r
+       #pragma warning(disable : 4786)\r
+#endif\r
+\r
+#include "ChainWalkContext.h"\r
+\r
+#include <ctype.h>\r
+\r
+//////////////////////////////////////////////////////////////////////\r
+\r
+string CChainWalkContext::m_sHashRoutineName;\r
+HASHROUTINE CChainWalkContext::m_pHashRoutine;\r
+int CChainWalkContext::m_nHashLen;\r
+int CChainWalkContext::m_nPlainLenMinTotal = 0;\r
+int CChainWalkContext::m_nPlainLenMaxTotal = 0;\r
+int CChainWalkContext::m_nHybridCharset = 0;\r
+bool CChainWalkContext::isOldRtFormat = false;\r
+bool CChainWalkContext::isRti2RtFormat = false;\r
+vector<stCharset> CChainWalkContext::m_vCharset;\r
+uint64 CChainWalkContext::m_nPlainSpaceUpToX[MAX_PLAIN_LEN + 1];\r
+uint64 CChainWalkContext::m_nPlainSpaceTotal;\r
+unsigned char CChainWalkContext::m_Salt[MAX_SALT_LEN];\r
+int CChainWalkContext::m_nSaltLen = 0;\r
+int CChainWalkContext::m_nRainbowTableIndex;\r
+uint64 CChainWalkContext::m_nReduceOffset;\r
+\r
+//////////////////////////////////////////////////////////////////////\r
+\r
+CChainWalkContext::CChainWalkContext()\r
+{\r
+}\r
+\r
+CChainWalkContext::~CChainWalkContext()\r
+{\r
+}\r
+\r
+bool CChainWalkContext::LoadCharset(string sName)\r
+{\r
+       m_vCharset.clear();\r
+       if (sName == "byte")\r
+       {\r
+               stCharset tCharset;\r
+               int i;\r
+               for (i = 0x00; i <= 0xff; i++)\r
+                       tCharset.m_PlainCharset[i] = (unsigned char) i;\r
+               tCharset.m_nPlainCharsetLen = 256;\r
+               tCharset.m_sPlainCharsetName = sName;\r
+               tCharset.m_sPlainCharsetContent = "0x00, 0x01, ... 0xff";\r
+               m_vCharset.push_back(tCharset);\r
+               return true;\r
+       }\r
+       if(sName.substr(0, 6) == "hybrid") // Hybrid charset consisting of 2 charsets\r
+               m_nHybridCharset = 1;           \r
+       else\r
+               m_nHybridCharset = 0;\r
+       \r
+       bool readCharset = false;\r
+       vector<string> vLine;\r
+\r
+       #ifdef BOINC\r
+               if ( boinc_ReadLinesFromFile( "charset.txt", vLine ) )\r
+                       readCharset = true;\r
+       #else\r
+               if ( ReadLinesFromFile("charset.txt", vLine) )\r
+                       readCharset = true;\r
+               else if ( ReadLinesFromFile(GetApplicationPath() + "charset.txt", vLine) )\r
+                       readCharset = true;\r
+       #endif\r
+\r
+       if ( readCharset )\r
+       {\r
+               uint32 i;\r
+               for (i = 0; i < vLine.size(); i++)\r
+               {\r
+                       // Filter comment\r
+                       if (vLine[i][0] == '#')\r
+                               continue;\r
+\r
+                       vector<string> vPart;\r
+                       if (SeperateString(vLine[i], "=", vPart))\r
+                       {\r
+                               // sCharsetName\r
+                               string sCharsetName = TrimString(vPart[0]);\r
+                               if (sCharsetName == "")\r
+                                       continue;\r
+                                                               \r
+                               // sCharsetName charset check\r
+                               bool fCharsetNameCheckPass = true;\r
+                               uint32 j;\r
+                               for (j = 0; j < sCharsetName.size(); j++)\r
+                               {\r
+                                       if (   !isalpha(sCharsetName[j])\r
+                                               && !isdigit(sCharsetName[j])\r
+                                               && (sCharsetName[j] != '-'))\r
+                                       {\r
+                                               fCharsetNameCheckPass = false;\r
+                                               break;\r
+                                       }\r
+                               }\r
+                               if (!fCharsetNameCheckPass)\r
+                               {\r
+                                       printf("invalid charset name %s in charset configuration file\n", sCharsetName.c_str());\r
+                                       continue;\r
+                               }\r
+\r
+                               // sCharsetContent\r
+                               string sCharsetContent = TrimString(vPart[1]);\r
+                               if (sCharsetContent == "" || sCharsetContent == "[]")\r
+                                       continue;\r
+                               if (sCharsetContent[0] != '[' || sCharsetContent[sCharsetContent.size() - 1] != ']')\r
+                               {\r
+                                       printf("invalid charset content %s in charset configuration file\n", sCharsetContent.c_str());\r
+                                       continue;\r
+                               }\r
+                               sCharsetContent = sCharsetContent.substr(1, sCharsetContent.size() - 2);\r
+                               if (sCharsetContent.size() > 256)\r
+                               {\r
+                                       printf("charset content %s too long\n", sCharsetContent.c_str());\r
+                                       continue;\r
+                               }\r
+\r
+                               //printf("%s = [%s]\n", sCharsetName.c_str(), sCharsetContent.c_str());\r
+\r
+                               // Is it the wanted charset?\r
+                               if(m_nHybridCharset == 1)\r
+                               {\r
+                                       vector<tCharset> vCharsets;\r
+                                       GetHybridCharsets(sName, vCharsets);\r
+                                       if(sCharsetName == vCharsets[m_vCharset.size()].sName)\r
+                                       {\r
+                                               stCharset tCharset;\r
+                                               tCharset.m_nPlainCharsetLen = sCharsetContent.size();                                                   \r
+                                               memcpy(tCharset.m_PlainCharset, sCharsetContent.c_str(), tCharset.m_nPlainCharsetLen);\r
+                                               tCharset.m_sPlainCharsetName = sCharsetName;\r
+                                               tCharset.m_sPlainCharsetContent = sCharsetContent;      \r
+                                               tCharset.m_nPlainLenMin = vCharsets[m_vCharset.size()].nPlainLenMin;\r
+                                               tCharset.m_nPlainLenMax = vCharsets[m_vCharset.size()].nPlainLenMax;\r
+                                               m_vCharset.push_back(tCharset);\r
+                                               if(vCharsets.size() == m_vCharset.size())\r
+                                                       return true;\r
+                                               i = 0; // Start the lookup over again for the next charset\r
+                                       }                                               \r
+                               }\r
+                               else if (sCharsetName == sName)\r
+                               {\r
+                                       stCharset tCharset;\r
+                                       tCharset.m_nPlainCharsetLen = sCharsetContent.size();                                                   \r
+                                       memcpy(tCharset.m_PlainCharset, sCharsetContent.c_str(), tCharset.m_nPlainCharsetLen);\r
+                                       tCharset.m_sPlainCharsetName = sCharsetName;\r
+                                       tCharset.m_sPlainCharsetContent = sCharsetContent;                                                      \r
+                                       m_vCharset.push_back(tCharset);\r
+                                       return true;\r
+                               }\r
+                       }\r
+               }\r
+               printf("charset %s not found in charset.txt\n", sName.c_str());\r
+       }\r
+       else\r
+               printf("can't open charset configuration file\n");\r
+\r
+       return false;\r
+}\r
+\r
+//////////////////////////////////////////////////////////////////////\r
+\r
+bool CChainWalkContext::SetHashRoutine(string sHashRoutineName)\r
+{\r
+       CHashRoutine hr;\r
+       hr.GetHashRoutine(sHashRoutineName, m_pHashRoutine, m_nHashLen);\r
+       if (m_pHashRoutine != NULL)\r
+       {\r
+               m_sHashRoutineName = sHashRoutineName;\r
+               return true;\r
+       }\r
+       else\r
+               return false;\r
+}\r
+\r
+bool CChainWalkContext::SetPlainCharset(string sCharsetName, int nPlainLenMin, int nPlainLenMax)\r
+{\r
+       // m_PlainCharset, m_nPlainCharsetLen, m_sPlainCharsetName, m_sPlainCharsetContent\r
+       if (!LoadCharset(sCharsetName))\r
+               return false;\r
+\r
+       if(m_vCharset.size() == 1) // Not hybrid charset\r
+       {\r
+               // m_nPlainLenMin, m_nPlainLenMax\r
+               if (nPlainLenMin < 1 || nPlainLenMax > MAX_PLAIN_LEN || nPlainLenMin > nPlainLenMax)\r
+               {\r
+                       printf("invalid plaintext length range: %d - %d\n", nPlainLenMin, nPlainLenMax);\r
+                       return false;\r
+               }\r
+               m_vCharset[0].m_nPlainLenMin = nPlainLenMin;\r
+               m_vCharset[0].m_nPlainLenMax = nPlainLenMax;\r
+       }\r
+       // m_nPlainSpaceUpToX\r
+       m_nPlainSpaceUpToX[0] = 0;\r
+       m_nPlainLenMaxTotal = 0;\r
+       m_nPlainLenMinTotal = 0;\r
+       uint64 nTemp = 1;\r
+       uint32 j, k = 1;\r
+       for(j = 0; j < m_vCharset.size(); j++)\r
+       {\r
+               int i;\r
+               m_nPlainLenMaxTotal += m_vCharset[j].m_nPlainLenMax;\r
+               m_nPlainLenMinTotal += m_vCharset[j].m_nPlainLenMin;\r
+               for (i = 1; i <= m_vCharset[j].m_nPlainLenMax; i++)\r
+               {                       \r
+                       nTemp *= m_vCharset[j].m_nPlainCharsetLen;\r
+                       if (i < m_vCharset[j].m_nPlainLenMin)\r
+                               m_nPlainSpaceUpToX[k] = 0;\r
+                       else\r
+                               m_nPlainSpaceUpToX[k] = m_nPlainSpaceUpToX[k - 1] + nTemp;\r
+                       k++;\r
+               }               \r
+       }\r
+       // m_nPlainSpaceTotal\r
+       m_nPlainSpaceTotal = m_nPlainSpaceUpToX[m_nPlainLenMaxTotal];\r
+\r
+       return true;\r
+}\r
+\r
+bool CChainWalkContext::SetRainbowTableIndex(int nRainbowTableIndex)\r
+{\r
+       if (nRainbowTableIndex < 0)\r
+               return false;\r
+       m_nRainbowTableIndex = nRainbowTableIndex;\r
+       m_nReduceOffset = 65536 * nRainbowTableIndex;\r
+\r
+       return true;\r
+}\r
+\r
+bool CChainWalkContext::SetSalt(unsigned char *Salt, int nSaltLength)\r
+{\r
+       memcpy(&m_Salt[0], Salt, nSaltLength);\r
+       \r
+       m_nSaltLen = nSaltLength;\r
+//     m_sSalt = sSalt;\r
+       return true;\r
+}\r
+\r
+bool CChainWalkContext::SetupWithPathName(string sPathName, int& nRainbowChainLen, int& nRainbowChainCount)\r
+{\r
+       // something like lm_alpha#1-7_0_100x16_test.rt\r
+\r
+#ifdef _WIN32\r
+       string::size_type nIndex = sPathName.find_last_of('\\');\r
+#else\r
+       string::size_type nIndex = sPathName.find_last_of('/');\r
+#endif\r
+       if (nIndex != string::npos)\r
+               sPathName = sPathName.substr(nIndex + 1);\r
+\r
+       if (sPathName.size() < 3)\r
+       {\r
+               printf("%s is not a rainbow table\n", sPathName.c_str());\r
+               return false;\r
+       }\r
+       if (sPathName.substr(sPathName.size() - 5) == ".rti2")\r
+       {\r
+               isRti2RtFormat = true;\r
+       }\r
+       else if (sPathName.substr(sPathName.size() - 4) == ".rti")\r
+       {\r
+               isOldRtFormat = false;\r
+       }\r
+       else if (sPathName.substr(sPathName.size() - 3) == ".rt")\r
+       {\r
+               isOldRtFormat = true;\r
+       }\r
+       else\r
+       {\r
+               printf("%s is not a rainbow table\n", sPathName.c_str());\r
+               return false;\r
+       }\r
+\r
+       // Parse\r
+       vector<string> vPart;\r
+       if (!SeperateString(sPathName, "___x_", vPart))\r
+       {\r
+               printf("filename %s not identified\n", sPathName.c_str());\r
+               return false;\r
+       }\r
+\r
+       string sHashRoutineName   = vPart[0];\r
+       int nRainbowTableIndex    = atoi(vPart[2].c_str());\r
+       nRainbowChainLen          = atoi(vPart[3].c_str());\r
+       nRainbowChainCount        = atoi(vPart[4].c_str());\r
+\r
+       // Parse charset definition\r
+       string sCharsetDefinition = vPart[1];\r
+       string sCharsetName;\r
+       int nPlainLenMin = 0, nPlainLenMax = 0;         \r
+\r
+//     printf("Charset: %s", sCharsetDefinition.c_str());\r
+       \r
+       if(sCharsetDefinition.substr(0, 6) == "hybrid") // Hybrid table\r
+       {\r
+               sCharsetName = sCharsetDefinition;\r
+       }\r
+       else\r
+       {\r
+               if ( sCharsetDefinition.find('#') == string::npos )             // For backward compatibility, "#1-7" is implied\r
+               {                       \r
+                       sCharsetName = sCharsetDefinition;\r
+                       nPlainLenMin = 1;\r
+                       nPlainLenMax = 7;\r
+               }\r
+               else\r
+               {\r
+                       vector<string> vCharsetDefinitionPart;\r
+                       if (!SeperateString(sCharsetDefinition, "#-", vCharsetDefinitionPart))\r
+                       {\r
+                               printf("filename %s not identified\n", sPathName.c_str());\r
+                               return false;   \r
+                       }\r
+                       else\r
+                       {\r
+                               sCharsetName = vCharsetDefinitionPart[0];\r
+                               nPlainLenMin = atoi(vCharsetDefinitionPart[1].c_str());\r
+                               nPlainLenMax = atoi(vCharsetDefinitionPart[2].c_str());\r
+                       }\r
+               }\r
+       }\r
+       // Setup\r
+       if (!SetHashRoutine(sHashRoutineName))\r
+       {\r
+               printf("hash routine %s not supported\n", sHashRoutineName.c_str());\r
+               return false;\r
+       }\r
+       if (!SetPlainCharset(sCharsetName, nPlainLenMin, nPlainLenMax))\r
+               return false;\r
+       if (!SetRainbowTableIndex(nRainbowTableIndex))\r
+       {\r
+               printf("invalid rainbow table index %d\n", nRainbowTableIndex);\r
+               return false;\r
+       }\r
+       m_nPlainSpaceTotal = m_nPlainSpaceUpToX[m_nPlainLenMaxTotal];\r
+       return true;\r
+}\r
+\r
+string CChainWalkContext::GetHashRoutineName()\r
+{\r
+       return m_sHashRoutineName;\r
+}\r
+\r
+int CChainWalkContext::GetHashLen()\r
+{\r
+       return m_nHashLen;\r
+}\r
+\r
+string CChainWalkContext::GetPlainCharsetName()\r
+{\r
+       return m_vCharset[0].m_sPlainCharsetName;\r
+}\r
+\r
+string CChainWalkContext::GetPlainCharsetContent()\r
+{\r
+       return m_vCharset[0].m_sPlainCharsetContent;\r
+}\r
+\r
+int CChainWalkContext::GetPlainLenMin()\r
+{\r
+       return m_vCharset[0].m_nPlainLenMin;\r
+}\r
+\r
+int CChainWalkContext::GetPlainLenMax()\r
+{\r
+       return m_vCharset[0].m_nPlainLenMax;\r
+}\r
+\r
+uint64 CChainWalkContext::GetPlainSpaceTotal()\r
+{\r
+       return m_nPlainSpaceTotal;\r
+}\r
+\r
+int CChainWalkContext::GetRainbowTableIndex()\r
+{\r
+       return m_nRainbowTableIndex;\r
+}\r
+\r
+void CChainWalkContext::Dump()\r
+{\r
+       printf("hash routine: %s\n", m_sHashRoutineName.c_str());\r
+       printf("hash length: %d\n", m_nHashLen);\r
+\r
+       printf( "m_vCharset[0].m_nPlainCharSetLen: %d\n", m_vCharset[0].m_nPlainCharsetLen );\r
+       printf( "m_vCharset[1].m_nPlainCharSetLen: %d\n", m_vCharset[1].m_nPlainCharsetLen );\r
+\r
+       printf("plain charset: ");\r
+       unsigned int i;\r
+       \r
+       for (i = 0; i < m_vCharset[0].m_nPlainCharsetLen; i++)\r
+       {\r
+               if (isprint(m_vCharset[0].m_PlainCharset[i]))\r
+                       printf("%c", m_vCharset[0].m_PlainCharset[i]);\r
+               else\r
+                       printf("?");\r
+       }\r
+       printf("\n");\r
+\r
+       printf("plain charset in hex: ");\r
+       for (i = 0; i < m_vCharset[0].m_nPlainCharsetLen; i++)\r
+               printf("%02x ", m_vCharset[0].m_PlainCharset[i]);\r
+       printf("\n");\r
+\r
+       printf("plain length range: %d - %d\n", m_vCharset[0].m_nPlainLenMin, m_vCharset[0].m_nPlainLenMax);\r
+       printf("plain charset name: %s\n", m_vCharset[0].m_sPlainCharsetName.c_str());\r
+       //printf("plain charset content: %s\n", m_sPlainCharsetContent.c_str());\r
+       //for (i = 0; i <= m_nPlainLenMax; i++)\r
+       //      printf("plain space up to %d: %s\n", i, uint64tostr(m_nPlainSpaceUpToX[i]).c_str());\r
+       printf("plain space total: %s\n", uint64tostr(m_nPlainSpaceTotal).c_str());\r
+\r
+       printf("rainbow table index: %d\n", m_nRainbowTableIndex);\r
+       printf("reduce offset: %s\n", uint64tostr(m_nReduceOffset).c_str());\r
+       printf("\n");\r
+}\r
+\r
+void CChainWalkContext::SetIndex(uint64 nIndex)\r
+{\r
+       m_nIndex = nIndex;\r
+}\r
+\r
+void CChainWalkContext::SetHash(unsigned char* pHash)\r
+{\r
+       memcpy(m_Hash, pHash, m_nHashLen);\r
+}\r
+\r
+void CChainWalkContext::IndexToPlain()\r
+{\r
+       int i;\r
+       m_nPlainLen = 0;\r
+///*\r
+       for (i = m_nPlainLenMaxTotal - 1; i >= m_nPlainLenMinTotal - 1; i--)\r
+       {\r
+               if (m_nIndex >= m_nPlainSpaceUpToX[i])\r
+               {\r
+                       m_nPlainLen = i + 1;\r
+                       break;\r
+               }\r
+       }\r
+\r
+       // this is an optimized version of the above\r
+/*\r
+       for (i = m_nPlainLenMaxTotal - 1; i >= m_nPlainLenMinTotal - 1\r
+               && m_nIndex < m_nPlainSpaceUpToX[i]; i--)\r
+       { }\r
+       \r
+       m_nPlainLen = i + 1;\r
+*/\r
+\r
+       if(m_nPlainLen == 0)\r
+               m_nPlainLen = m_nPlainLenMinTotal;\r
+       uint64 nIndexOfX = m_nIndex - m_nPlainSpaceUpToX[m_nPlainLen - 1];\r
+\r
+// this is the generic code for non x86/x86_64 platforms\r
+#if !defined(_M_X64) && !defined(_M_IX86) && !defined(__i386__) && !defined(__x86_64__)\r
+       \r
+       // generic version (slow for non 64-bit platforms and gcc < 4.5.x)\r
+       for (i = m_nPlainLen - 1; i >= 0; i--)\r
+       {\r
+               int nCharsetLen = 0;\r
+               for(uint32 j = 0; j < m_vCharset.size(); j++)\r
+               {\r
+                       nCharsetLen += m_vCharset[j].m_nPlainLenMax;\r
+                       if(i < nCharsetLen) // We found the correct charset\r
+                       {\r
+                               m_Plain[i] = m_vCharset[j].m_PlainCharset[nIndexOfX % m_vCharset[j].m_nPlainCharsetLen];\r
+                               nIndexOfX /= m_vCharset[j].m_nPlainCharsetLen;\r
+                               break;\r
+                       }\r
+               }\r
+       }\r
+\r
+#elif defined(_M_X64) || defined(_M_IX86) || defined(__i386__) || defined(__x86_64__)\r
+\r
+       // Fast ia32 version\r
+       for (i = m_nPlainLen - 1; i >= 0; i--)\r
+       {\r
+               // 0x100000000 = 2^32\r
+#ifdef _M_IX86\r
+               if (nIndexOfX < 0x100000000I64)\r
+                       break;\r
+#else\r
+               if (nIndexOfX < 0x100000000llu)\r
+                       break;\r
+#endif\r
+\r
+               int nCharsetLen = 0;\r
+               for(uint32 j = 0; j < m_vCharset.size(); j++)\r
+               {\r
+                       nCharsetLen += m_vCharset[j].m_nPlainLenMax;\r
+                       if(i < nCharsetLen) // We found the correct charset\r
+                       {\r
+                               m_Plain[i] = m_vCharset[j].m_PlainCharset[nIndexOfX % m_vCharset[j].m_nPlainCharsetLen];\r
+                               nIndexOfX /= m_vCharset[j].m_nPlainCharsetLen;\r
+                               break;\r
+                       }\r
+               }\r
+       }\r
+\r
+       uint32 nIndexOfX32 = (uint32)nIndexOfX;\r
+       for (; i >= 0; i--)\r
+       {\r
+               int nCharsetLen = 0;\r
+               for(uint32 j = 0; j < m_vCharset.size(); j++)\r
+               {\r
+                       nCharsetLen += m_vCharset[j].m_nPlainLenMax;\r
+                       if(i < nCharsetLen) // We found the correct charset\r
+                       {\r
+\r
+//             m_Plain[i] = m_vCharset[j].m_PlainCharset[nIndexOfX32 % m_vCharset[j].m_nPlainCharsetLen];\r
+//             nIndexOfX32 /= m_vCharset[j].m_nPlainCharsetLen;\r
+\r
+//     moving nPlainCharsetLen into the asm body and avoiding the extra temp\r
+//     variable results in a performance gain\r
+//                             unsigned int nPlainCharsetLen = m_vCharset[j].m_nPlainCharsetLen;\r
+                               unsigned int nTemp;\r
+\r
+#if defined(_WIN32) && !defined(__GNUC__)\r
+               // VC++ still needs this\r
+               unsigned int nPlainCharsetLen = m_vCharset[j].m_nPlainCharsetLen;\r
+\r
+               __asm\r
+               {\r
+                       mov eax, nIndexOfX32\r
+                       xor edx, edx\r
+                       div nPlainCharsetLen\r
+                       mov nIndexOfX32, eax\r
+                       mov nTemp, edx\r
+               }\r
+               m_Plain[i] = m_vCharset[j].m_PlainCharset[nTemp];\r
+#else\r
+               __asm__ __volatile__ ("xor %%edx, %%edx;"\r
+                                                               "divl %3;"\r
+                                                               : "=a"(nIndexOfX32), "=d"(nTemp)\r
+                                                               : "a"(nIndexOfX32), "rm"(m_vCharset[j].m_nPlainCharsetLen)\r
+                                                               : );\r
+               m_Plain[i] = m_vCharset[j].m_PlainCharset[nTemp];\r
+#endif\r
+               break;\r
+                       }\r
+               }\r
+       }\r
+#endif\r
+}\r
+\r
+void CChainWalkContext::PlainToHash()\r
+{      \r
+       m_pHashRoutine(m_Plain, m_nPlainLen, m_Hash);\r
+}\r
+\r
+void CChainWalkContext::HashToIndex(int nPos)\r
+{\r
+       m_nIndex = (*(uint64*)m_Hash + m_nReduceOffset + nPos) % m_nPlainSpaceTotal;\r
+}\r
+\r
+uint64 CChainWalkContext::GetIndex()\r
+{\r
+       return m_nIndex;\r
+}\r
+const uint64 *CChainWalkContext::GetIndexPtr()\r
+{\r
+       return &m_nIndex;\r
+}\r
+\r
+string CChainWalkContext::GetPlain()\r
+{\r
+       string sRet;\r
+       int i;\r
+       for (i = 0; i < m_nPlainLen; i++)\r
+       {\r
+               char c = m_Plain[i];\r
+               sRet += c;\r
+       }\r
+       \r
+       return sRet;\r
+}\r
+\r
+string CChainWalkContext::GetBinary()\r
+{\r
+       return HexToStr(m_Plain, m_nPlainLen);\r
+}\r
+\r
+string CChainWalkContext::GetHash()\r
+{\r
+       return HexToStr(m_Hash, m_nHashLen);\r
+}\r
+\r
+bool CChainWalkContext::CheckHash(unsigned char* pHash)\r
+{\r
+       if (memcmp(m_Hash, pHash, m_nHashLen) == 0)\r
+               return true;\r
+\r
+       return false;\r
+}\r
+\r
+bool CChainWalkContext::isOldFormat()\r
+{\r
+       return isOldRtFormat;\r
+}\r
+\r
+bool CChainWalkContext::isRti2Format()\r
+{\r
+       return isRti2RtFormat;\r
+}\r