github.com/code-to-go/safepool.lib@v0.0.0-20221205180519-ee25e63c226e/algo/merkle.go (about)

     1  package algo
     2  
     3  import (
     4  	"hash"
     5  	"io"
     6  	"os"
     7  )
     8  
     9  type MerkleTree struct {
    10  	DataLength uint32
    11  	Blocks     []HashBlock
    12  }
    13  
    14  var UseSimd bool
    15  
    16  func MerkleTreeFromFile(name string, splitBits uint) (MerkleTree, error) {
    17  	f, err := os.Open(name)
    18  	if err != nil {
    19  		return MerkleTree{}, err
    20  	}
    21  	defer f.Close()
    22  
    23  	return MerkleTreeFromReader(f, splitBits)
    24  }
    25  
    26  func MerkleTreeFromReader(r io.Reader, splitBits uint) (MerkleTree, error) {
    27  	blocks, err := HashSplit(r, splitBits, nil)
    28  	if err != nil {
    29  		return MerkleTree{}, err
    30  	}
    31  
    32  	start := 0
    33  	for start < len(blocks)-1 {
    34  		//		blocks, start = buildMerkleRow(blake, length, blocks, start)
    35  	}
    36  
    37  	return MerkleTree{
    38  		Blocks: blocks,
    39  	}, nil
    40  }
    41  
    42  // buildMerkleRow calculates a new row of a Merkle tree starting from start position until the end of the
    43  func buildMerkleRow(blake hash.Hash, fileLength uint32, blocks []HashBlock, start int) (blocks2 []HashBlock, start2 int) {
    44  	l := len(blocks)
    45  	if l%2 == 1 {
    46  		blocks = append(blocks, getHashBlock(blake, fileLength))
    47  		l++
    48  	}
    49  
    50  	for i := start; i < l; i += 2 {
    51  		block := getHashBlock(blake, blocks[i].Length, blocks[i].Hash[:], blocks[i+1].Hash[:])
    52  		blocks = append(blocks, block)
    53  	}
    54  	return blocks, l
    55  }
    56  
    57  func MerkleTreeRoot(m MerkleTree) (HashBlock, int) {
    58  	l := len(m.Blocks) - 1
    59  	return m.Blocks[l], l
    60  }
    61  
    62  func MerkleTreeHash(m MerkleTree) *[]byte {
    63  	l := len(m.Blocks) - 1
    64  	return &m.Blocks[l].Hash
    65  }
    66  
    67  func MerkleTreeAt(m MerkleTree, idx int) (block HashBlock, length uint32) {
    68  	block = m.Blocks[idx]
    69  	if idx+1 == len(m.Blocks) || m.Blocks[idx+1].Length <= m.Blocks[idx].Length {
    70  		return block, m.DataLength - block.Length
    71  	} else {
    72  		return block, m.Blocks[idx+1].Length - block.Length
    73  	}
    74  }
    75  
    76  func MerkleTreeChildren(m MerkleTree, idx int) (left int, right int) {
    77  	return 0, 0
    78  }
    79  
    80  func min(a, b int) int {
    81  	if a < b {
    82  		return a
    83  	} else {
    84  		return b
    85  	}
    86  }