private unsafe Blake3Node RootNode() { var result = ChunkState.Node(); var temp = new uint[8]; var trailingZeros64 = TrailingZeros64(Used); var len64 = Len64(Used); fixed(uint *ptrTemp = temp) { int idx; for (idx = trailingZeros64; idx < len64; idx++) { if (!HasSubTreeAtHeight(idx)) { continue; } result.ChainingValue(ptrTemp); result = Blake3Node.ParentNode(Stack[idx], temp, Key, Flags); } } result.Flags |= flagRoot; return(result); }
} // end function HasSubTreeAtHeight // AddChunkChainingValue appends a chunk to the right edge of the Merkle tree. private void AddChunkChainingValue(UInt32[] a_CV) { // seek to first open stack slot, merging subtrees as we go Int32 LIdx = 0; while (HasSubTreeAtHeight(LIdx)) { Blake3Node.ParentNode(Stack[LIdx], a_CV, Key, Flags).ChainingValue(ref a_CV); LIdx++; } Stack[LIdx] = a_CV.DeepCopy(); Used++; } // end function AddChunkChainingValue
// AddChunkChainingValue appends a chunk to the right edge of the Merkle tree. private unsafe void AddChunkChainingValue(uint[] cv) { // seek to first open stack slot, merging subtrees as we go var idx = 0; fixed(uint *cvPtr = cv) { while (HasSubTreeAtHeight(idx)) { Blake3Node.ParentNode(Stack[idx], cv, Key, Flags).ChainingValue(cvPtr); idx++; } } Stack[idx] = ArrayUtils.Clone(cv); Used++; }
}; // end struct Blake3OutputReader private Blake3Node RootNode() { Int32 LIdx, LTrailingZeros64, LLen64; Blake3Node result = CS.Node(); UInt32[] LTemp = new UInt32[8]; LTrailingZeros64 = TrailingZeros64(Used); LLen64 = Len64(Used); for (LIdx = LTrailingZeros64; LIdx < LLen64; LIdx++) { if (HasSubTreeAtHeight(LIdx)) { result.ChainingValue(ref LTemp); result = Blake3Node.ParentNode(Stack[LIdx], LTemp, Key, Flags); } } result.Flags = result.Flags | flagRoot; return(result); } // end function RootNode