public virtual bool LoadLowestLevelHashs(FileDataIO fileInput) { if (DataSize <= BaseSize) { // sanity // lowest level, read hash Hash.Read(fileInput); //theApp.AddDebugLogLine(false,Hash.GetString()); HashValid = true; return(true); } else { ulong nBlocks = DataSize / BaseSize + ((DataSize % BaseSize != 0) ? (ulong)1 : (ulong)0); ulong nLeft = (((IsLeftBranch) ? nBlocks + 1 : nBlocks) / 2) * BaseSize; ulong nRight = DataSize - nLeft; if (LeftTree == null) { LeftTree = MuleApplication.Instance.AICHObjectManager.CreateAICHHashTree(nLeft, true, (nLeft <= MuleConstants.PARTSIZE) ? MuleConstants.EMBLOCKSIZE : MuleConstants.PARTSIZE); } if (RightTree == null) { RightTree = MuleApplication.Instance.AICHObjectManager.CreateAICHHashTree(nRight, false, (nRight <= MuleConstants.PARTSIZE) ? MuleConstants.EMBLOCKSIZE : MuleConstants.PARTSIZE); } return(LeftTree.LoadLowestLevelHashs(fileInput) && RightTree.LoadLowestLevelHashs(fileInput)); } }
private bool hashValid_; // the hash is valid and not empty #endregion #region Constructors public AICHHashTreeImpl(ulong nDataSize, bool bLeftBranch, ulong nBaseSize) { dataSize_ = nDataSize; baseSize_ = nBaseSize; isLeftBranch_ = bLeftBranch; leftTree_ = null; rightTree_ = null; hashValid_ = false; }
public AICHHashTree Create(long startpos, long length, bool islefttree) { long blocks; AICHHashTree node = new AICHHashTree(); node.DataSize = length; if (length > EMPARTSIZE) { node.BaseSize = EMPARTSIZE; } else if (length <= EMPARTSIZE && length > EMBLOCKSIZE) { node.BaseSize = EMBLOCKSIZE; } else if (length <= EMBLOCKSIZE && length > 0) { _blockHashes.Add(node); return(node); } if (node.DataSize % node.BaseSize == 0) { blocks = node.DataSize / node.BaseSize; } else { blocks = node.DataSize / node.BaseSize + 1; } long leftsize, rightsize; if (blocks % 2 == 0) { leftsize = blocks / 2 * node.BaseSize; } else { if (islefttree) { leftsize = (blocks + 1) / 2 * node.BaseSize; } else { leftsize = blocks / 2 * node.BaseSize; } } rightsize = node.DataSize - leftsize; node.LeftTree = Create(startpos, leftsize, true); node.RightTree = Create(startpos + leftsize, rightsize, false); return(node); }
public bool VerifyAICHHashSet() { if (m_rFileSize == 0 || !HasAICHHash) { return(false); } if (!HasExpectedAICHHashCount) { return(false); } AICHRecoveryHashSet tmpAICHHashSet = MuleApplication.Instance.AICHObjectManager.CreateAICHRecoveryHashSet(null, m_rFileSize); tmpAICHHashSet.SetMasterHash(AICHHash, AICHStatusEnum.AICH_HASHSETCOMPLETE); uint uPartCount = (uint)((m_rFileSize + MuleConstants.PARTSIZE - 1) / MuleConstants.PARTSIZE); if (uPartCount <= 1) { return(true); // No AICH Part Hashs } for (uint nPart = 0; nPart < uPartCount; nPart++) { ulong nPartStartPos = (ulong)nPart * MuleConstants.PARTSIZE; uint nPartSize = (uint)Math.Min(MuleConstants.PARTSIZE, (ulong)FileSize - nPartStartPos); AICHHashTree pPartHashTree = tmpAICHHashSet.HashTree.FindHash(nPartStartPos, nPartSize); if (pPartHashTree != null) { pPartHashTree.Hash = this.RawAICHHashSet[(int)nPart]; pPartHashTree.HashValid = true; } else { return(false); } } if (!tmpAICHHashSet.VerifyHashTree(false)) { m_aAICHPartHashSet.Clear(); return(false); } else { return(true); } }
public void CalcAICH(byte[] buffer, int pos, int length) { int currentPos = pos; int posLimit = pos + length; while (currentPos < posLimit) { AICHHashTree currentNode = _blockHashes[_currentIndex]; int writeCount = (int)Math.Min(length, currentNode.DataSize - _currentBlockData.Length); _currentBlockData.Write(buffer, currentPos, writeCount); length -= writeCount; currentPos += writeCount; FinishedSize += writeCount; if (_currentBlockData.Length <= currentNode.DataSize) { _currentBlockData.Seek(0, SeekOrigin.Begin); currentNode.Hash = sha1.ComputeHash(_currentBlockData); _currentBlockData.SetLength(0); _currentIndex++; } } }
public void SetBlockHash(ulong nSize, ulong nStartPos, AICHHashAlgorithm pHashAlg) { byte nLevel = 0; AICHHashTree pToInsert = FindHash(nStartPos, nSize, ref nLevel); if (pToInsert == null) { // sanity //TODO:Log //theApp.QueueDebugLogLine(/*DLP_VERYHIGH,*/ false, _T("Critical Error: Failed to Insert SHA-HashBlock, FindHash() failed!")); return; } //sanity if (pToInsert.BaseSize != MuleConstants.EMBLOCKSIZE || pToInsert.DataSize != nSize) { //TODO:Log //theApp.QueueDebugLogLine(/*DLP_VERYHIGH,*/ false, _T("Critical Error: Logical error on values in SetBlockHashFromData")); return; } pHashAlg.Finish(pToInsert.Hash); pToInsert.HashValid = true; }
public AICHHash(long fileLength) { _fileLength = fileLength; _rootNode = Create(0, fileLength, true); }
public AICHHashTree FindHash(ulong nStartPos, ulong nSize, ref byte nLevel) { nLevel++; if (nLevel > 22) { // sanity return(null); } if (nStartPos + nSize > dataSize_) { // sanity return(null); } if (nSize > dataSize_) { // sanity return(null); } if (nStartPos == 0 && nSize == dataSize_) { // this is the searched hash return(this); } else if (dataSize_ <= baseSize_) { // sanity // this is already the last level, cant go deeper return(null); } else { ulong nBlocks = dataSize_ / baseSize_ + ((dataSize_ % baseSize_ != 0) ? (ulong)1 : (ulong)0); ulong nLeft = (((isLeftBranch_) ? nBlocks + 1 : nBlocks) / 2) * baseSize_; ulong nRight = dataSize_ - nLeft; if (nStartPos < nLeft) { if (nStartPos + nSize > nLeft) { // sanity return(null); } if (leftTree_ == null) { leftTree_ = MuleApplication.Instance.AICHObjectManager.CreateAICHHashTree(nLeft, true, (nLeft <= MuleConstants.PARTSIZE) ? MuleConstants.EMBLOCKSIZE : MuleConstants.PARTSIZE); } return(leftTree_.FindHash(nStartPos, nSize, ref nLevel)); } else { nStartPos -= nLeft; if (nStartPos + nSize > nRight) { // sanity return(null); } if (rightTree_ == null) { rightTree_ = MuleApplication.Instance.AICHObjectManager.CreateAICHHashTree(nRight, false, (nRight <= MuleConstants.PARTSIZE) ? MuleConstants.EMBLOCKSIZE : MuleConstants.PARTSIZE); } return(leftTree_.FindHash(nStartPos, nSize, ref nLevel)); } } }
public bool VerifyHashTree(AICHHashAlgorithm hashalg, bool bDeleteBadTrees) { if (!HashValid) { if (bDeleteBadTrees) { leftTree_ = null; rightTree_ = null; } //TODO: Log //theApp.QueueDebugLogLine(/*DLP_HIGH,*/ false, _T("VerifyHashTree - No masterhash available")); return(false); } // calculated missing hashs without overwriting anything if (leftTree_ != null && !leftTree_.HashValid) { leftTree_.ReCalculateHash(hashalg, true); } if (rightTree_ != null && !rightTree_.HashValid) { rightTree_.ReCalculateHash(hashalg, true); } if ((rightTree_ != null && rightTree_.HashValid) ^ (leftTree_ != null && leftTree_.HashValid)) { // one branch can never be verified if (bDeleteBadTrees) { leftTree_ = null; rightTree_ = null; } //TODO: Log //theApp.QueueDebugLogLine(/*DLP_HIGH,*/ false, _T("VerifyHashSet failed - Hashtree incomplete")); return(false); } if ((rightTree_ != null && rightTree_.HashValid) && (leftTree_ != null && leftTree_.HashValid)) { // check verify the hashs of both child nodes against my hash AICHHash CmpHash = MuleApplication.Instance.AICHObjectManager.CreateAICHHash(); hashalg.Reset(); hashalg.Add(leftTree_.Hash.RawHash); hashalg.Add(rightTree_.Hash.RawHash); hashalg.Finish(CmpHash); if (!Hash.Equals(CmpHash)) { if (bDeleteBadTrees) { leftTree_ = null; rightTree_ = null; } return(false); } return(leftTree_.VerifyHashTree(hashalg, bDeleteBadTrees) && rightTree_.VerifyHashTree(hashalg, bDeleteBadTrees)); } else { // last hash in branch - nothing below to verify return(true); } }
public bool SetHash(FileDataIO fileInput, uint wHashIdent, sbyte nLevel, bool bAllowOverwrite) { if (nLevel == -1) { // first call, check how many level we need to go byte i; for (i = 0; i != 32 && (wHashIdent & 0x80000000) == 0; i++) { wHashIdent <<= 1; } if (i > 31) { //TODO:Log //theApp.QueueDebugLogLine(/*DLP_HIGH,*/ false, _T("CAICHHashTree::SetHash - found invalid HashIdent (0)")); return(false); } else { nLevel = (sbyte)(31 - i); } } if (nLevel == 0) { // this is the searched hash if (HashValid && !bAllowOverwrite) { // not allowed to overwrite this hash, however move the filepointer by reading a hash AICHHash hash = MuleApplication.Instance.AICHObjectManager.CreateAICHHash(fileInput); return(true); } Hash.Read(fileInput); HashValid = true; return(true); } else if (DataSize <= BaseSize) { // sanity // this is already the last level, cant go deeper return(false); } else { // adjust ident to point the path to the next node wHashIdent <<= 1; nLevel--; ulong nBlocks = DataSize / BaseSize + ((DataSize % BaseSize != 0) ? (ulong)1 : (ulong)0); ulong nLeft = (((IsLeftBranch) ? nBlocks + 1 : nBlocks) / 2) * BaseSize; ulong nRight = DataSize - nLeft; if ((wHashIdent & 0x80000000) > 0) { if (LeftTree == null) { LeftTree = MuleApplication.Instance.AICHObjectManager.CreateAICHHashTree(nLeft, true, (nLeft <= MuleConstants.PARTSIZE) ? MuleConstants.EMBLOCKSIZE : MuleConstants.PARTSIZE); } return(LeftTree.SetHash(fileInput, wHashIdent, nLevel)); } else { if (RightTree == null) { RightTree = MuleApplication.Instance.AICHObjectManager.CreateAICHHashTree(nRight, false, (nRight <= MuleConstants.PARTSIZE) ? MuleConstants.EMBLOCKSIZE : MuleConstants.PARTSIZE); } return(RightTree.SetHash(fileInput, wHashIdent, nLevel)); } } }