mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-27 07:06:42 +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"
|
"bytes"
|
||||||
_ "crypto/sha256"
|
_ "crypto/sha256"
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"hash"
|
||||||
|
"io"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/crypto/sha3"
|
"github.com/ethereum/go-ethereum/crypto/sha3"
|
||||||
)
|
)
|
||||||
|
|
||||||
var hashFunc Hasher = sha3.NewKeccak256 //default hasher
|
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
|
// A merkle tree for a user that stores the entire tree
|
||||||
// Specifically this tree is left a leaning balanced binary tree
|
// Specifically this tree is left a leaning balanced binary tree
|
||||||
// Where each node holds the hash of its leaves
|
// 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))
|
hash := h.Sum(make([]byte, 0))
|
||||||
return hash, ok
|
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) {
|
func TestBuildBMT(t *testing.T) {
|
||||||
|
|
||||||
// Grab some data to make the tree out of, and partition
|
// Grab some data to make the tree out of, and partition
|
||||||
|
|
@ -50,7 +79,7 @@ func TestBuildBMT(t *testing.T) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
tree, r, count, err1 := BuildBMT(sha3.NewKeccak256, data, 32)
|
tree, r, count, err1 := BuildBMT(sha3.NewKeccak256, data, 1)
|
||||||
|
|
||||||
switch err1 {
|
switch err1 {
|
||||||
case -1:
|
case -1:
|
||||||
|
|
@ -61,7 +90,7 @@ func TestBuildBMT(t *testing.T) {
|
||||||
t.Errorf("BMT leaf count validation error")
|
t.Errorf("BMT leaf count validation error")
|
||||||
return
|
return
|
||||||
case 0:
|
case 0:
|
||||||
fmt.Println("Build BMT OK")
|
fmt.Println("Build BMT OK ", count)
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Println(tree.Root())
|
fmt.Println(tree.Root())
|
||||||
|
|
@ -76,6 +105,7 @@ func TestBuildBMT(t *testing.T) {
|
||||||
t.Errorf("proof %d failed", i)
|
t.Errorf("proof %d failed", i)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
fmt.Println("done")
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestBuildBMT2(t *testing.T) {
|
func TestBuildBMT2(t *testing.T) {
|
||||||
|
|
@ -88,7 +118,7 @@ func TestBuildBMT2(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Println(len(data))
|
fmt.Println(len(data))
|
||||||
blocks := splitData(data, 32)
|
blocks := splitData(data, 2)
|
||||||
|
|
||||||
count := len(blocks)
|
count := len(blocks)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -51,7 +51,8 @@ data_{i} := size(subtree_{i}) || key_{j} || key_{j+1} .... || key_{j+n-1}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const (
|
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
|
// defaultHash = "SHA256" // http://golang.org/pkg/hash/#Hash
|
||||||
defaultBranches int64 = 128
|
defaultBranches int64 = 128
|
||||||
// hashSize int64 = hasherfunc.New().Size() // hasher knows about its own length in bytes
|
// 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
|
return crypto.SHA256.New
|
||||||
case "SHA3":
|
case "SHA3":
|
||||||
return sha3.NewKeccak256
|
return sha3.NewKeccak256
|
||||||
|
case "BMTSHA3":
|
||||||
|
return NewBMTSHA3
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue