mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-27 15:16:43 +00:00
swarm/storage add hash.Hash interface for BMT .
Integrate with chunker.go
This commit is contained in:
parent
eab1384b08
commit
44a9a39c84
4 changed files with 106 additions and 4 deletions
|
|
@ -6,13 +6,21 @@ import (
|
|||
"bytes"
|
||||
_ "crypto/sha256"
|
||||
"encoding/binary"
|
||||
"errors"
|
||||
"fmt"
|
||||
"hash"
|
||||
"io"
|
||||
|
||||
"github.com/ethereum/go-ethereum/crypto/sha3"
|
||||
)
|
||||
|
||||
var hashFunc Hasher = sha3.NewKeccak256 //default hasher
|
||||
|
||||
type state struct {
|
||||
btree BTree
|
||||
root Root
|
||||
}
|
||||
|
||||
// A merkle tree for a user that stores the entire tree
|
||||
// Specifically this tree is left a leaning balanced binary tree
|
||||
// Where each node holds the hash of its leaves
|
||||
|
|
@ -313,3 +321,64 @@ func checkNode(height int, proof [][]byte, index, count uint64) ([]byte, bool) {
|
|||
hash := h.Sum(make([]byte, 0))
|
||||
return hash, ok
|
||||
}
|
||||
|
||||
// ShakeHash defines the interface to hash functions that
|
||||
// support arbitrary-length output.
|
||||
type BMTHash interface {
|
||||
// Write absorbs more data into the hash's state. It panics if input is
|
||||
// written to it after output has been read from it.
|
||||
io.Writer
|
||||
|
||||
// Read reads more output from the hash; reading affects the hash's
|
||||
// state. (ShakeHash.Read is thus very different from Hash.Sum)
|
||||
// It never returns an error.
|
||||
io.Reader
|
||||
|
||||
// Clone returns a copy of the ShakeHash in its current state.
|
||||
Clone() BMTHash
|
||||
|
||||
// Reset resets the ShakeHash to its initial state.
|
||||
Reset()
|
||||
}
|
||||
|
||||
// Reset clears the internal state by zeroing the sponge state and
|
||||
func (d *state) Reset() {
|
||||
d.root = Root{Count: 0, Base: nil}
|
||||
d.btree = BTree{count: 0, root: nil, rootHash: nil}
|
||||
}
|
||||
|
||||
// Write absorbs more data into the hash's state. It produces an error
|
||||
// if more data is written to the ShakeHash after writing
|
||||
func (d *state) Write(p []byte) (written int, err error) {
|
||||
tree, r, count, err1 := BuildBMT(hashFunc, p, 32)
|
||||
d.btree = *tree
|
||||
d.root = *r
|
||||
|
||||
if err1 != 0 {
|
||||
err = errors.New("bmt write error")
|
||||
}
|
||||
|
||||
return count, err
|
||||
}
|
||||
|
||||
func (d *state) Get(p []byte) (written int) {
|
||||
return 3
|
||||
}
|
||||
|
||||
// Sum return the root hash of the BMT
|
||||
func (d *state) Sum(in []byte) []byte {
|
||||
return d.root.Base
|
||||
}
|
||||
|
||||
// BlockSize returns the rate of sponge underlying this hash function.
|
||||
func (d *state) BlockSize() int { return 0 }
|
||||
|
||||
// Size returns the output size of the hash function in bytes.
|
||||
func (d *state) Size() int { return 32 }
|
||||
|
||||
// NewBMTSHA3 creates a new BMT hash
|
||||
func NewBMTSHA3() hash.Hash {
|
||||
tmpbtree := BTree{count: 0, root: nil, rootHash: nil}
|
||||
troot := Root{Count: 0, Base: nil}
|
||||
return &state{btree: tmpbtree, root: troot}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -41,6 +41,35 @@ func TestGetHeight2(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestBuildBMT3(t *testing.T) {
|
||||
|
||||
// Grab some data to make the tree out of, and partition
|
||||
data, err := ioutil.ReadFile("binarymerkle_test.go") // assume testdata exists
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
return
|
||||
}
|
||||
var thashFunc = MakeHashFunc("BMTSHA3")
|
||||
var h = thashFunc()
|
||||
h.Reset()
|
||||
h.Write(data)
|
||||
var key = h.Sum(nil)
|
||||
|
||||
fmt.Println(key)
|
||||
|
||||
// for i := 0; i < count; i++ {
|
||||
// p := tree.InclusionProof(i)
|
||||
//
|
||||
// fmt.Println(p)
|
||||
//
|
||||
// ok := r.CheckProof(sha3.NewKeccak256, p, i)
|
||||
// if !ok {
|
||||
// t.Errorf("proof %d failed", i)
|
||||
// }
|
||||
// }
|
||||
// fmt.Println("done")
|
||||
}
|
||||
|
||||
func TestBuildBMT(t *testing.T) {
|
||||
|
||||
// Grab some data to make the tree out of, and partition
|
||||
|
|
@ -50,7 +79,7 @@ func TestBuildBMT(t *testing.T) {
|
|||
return
|
||||
}
|
||||
|
||||
tree, r, count, err1 := BuildBMT(sha3.NewKeccak256, data, 32)
|
||||
tree, r, count, err1 := BuildBMT(sha3.NewKeccak256, data, 1)
|
||||
|
||||
switch err1 {
|
||||
case -1:
|
||||
|
|
@ -61,7 +90,7 @@ func TestBuildBMT(t *testing.T) {
|
|||
t.Errorf("BMT leaf count validation error")
|
||||
return
|
||||
case 0:
|
||||
fmt.Println("Build BMT OK")
|
||||
fmt.Println("Build BMT OK ", count)
|
||||
}
|
||||
|
||||
fmt.Println(tree.Root())
|
||||
|
|
@ -76,6 +105,7 @@ func TestBuildBMT(t *testing.T) {
|
|||
t.Errorf("proof %d failed", i)
|
||||
}
|
||||
}
|
||||
fmt.Println("done")
|
||||
}
|
||||
|
||||
func TestBuildBMT2(t *testing.T) {
|
||||
|
|
@ -88,7 +118,7 @@ func TestBuildBMT2(t *testing.T) {
|
|||
}
|
||||
|
||||
fmt.Println(len(data))
|
||||
blocks := splitData(data, 32)
|
||||
blocks := splitData(data, 2)
|
||||
|
||||
count := len(blocks)
|
||||
|
||||
|
|
|
|||
|
|
@ -51,7 +51,8 @@ data_{i} := size(subtree_{i}) || key_{j} || key_{j+1} .... || key_{j+n-1}
|
|||
*/
|
||||
|
||||
const (
|
||||
defaultHash = "SHA3" // http://golang.org/pkg/hash/#Hash
|
||||
//defaultHash = "SHA3"
|
||||
defaultHash = "BMTSHA3" // http://golang.org/pkg/hash/#Hash
|
||||
// defaultHash = "SHA256" // http://golang.org/pkg/hash/#Hash
|
||||
defaultBranches int64 = 128
|
||||
// hashSize int64 = hasherfunc.New().Size() // hasher knows about its own length in bytes
|
||||
|
|
|
|||
|
|
@ -83,6 +83,8 @@ func MakeHashFunc(hash string) Hasher {
|
|||
return crypto.SHA256.New
|
||||
case "SHA3":
|
||||
return sha3.NewKeccak256
|
||||
case "BMTSHA3":
|
||||
return NewBMTSHA3
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue