package pieces import ( // "fmt" "github.com/minio/sha256-simd" "fil_integrate/build/cid" "fil_integrate/build/state-types/abi" ) const ( LEFT byte = 0 RIGHT byte = 1 ) type MerkleProof struct { Data []cid.Commit Path []byte } func (proof *MerkleProof) Add(hash cid.Commit, path byte) { proof.Data = append(proof.Data, hash) proof.Path = append(proof.Path, path) } func (proof *MerkleProof) Verify(data []byte, finalRoot cid.Commit, dataOffset abi.PaddedPieceSize) (bool, error) { ok := proof.verifyMerklePath(dataOffset, abi.UnpaddedPieceSize(len(data)).Padded()) if !ok { return false, nil } root, err := GeneratePieceCommitmentFast(data, abi.UnpaddedPieceSize(len(data))) if err != nil { return false, err } for index, hash := range proof.Data { h := sha256.New() if proof.Path[index] == LEFT { h.Write(hash[:]) h.Write(root[:]) } else { h.Write(root[:]) h.Write(hash[:]) } res := h.Sum(nil) trim_to_fr32(res[:32]) copy(root[:], res) } return root == finalRoot, nil } func (proof *MerkleProof) verifyMerklePath(offset abi.PaddedPieceSize, size abi.PaddedPieceSize) bool { for size > 1 { size >>= 1 offset >>= 1 } for _, path := range proof.Path { index := (offset >> 1) << 1 if index != offset { if path != LEFT { return false } } else { if path != RIGHT { return false } } offset >>= 1 } return true }