-
Notifications
You must be signed in to change notification settings - Fork 87
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
#133 CID rank merkle proofs. Merkle tree improvements
- Loading branch information
1 parent
04e54a1
commit f0244d7
Showing
6 changed files
with
278 additions
and
129 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
package merkle | ||
|
||
type Node struct { | ||
hash []byte | ||
|
||
parent *Node | ||
left *Node | ||
right *Node | ||
|
||
// first index of elements in this node subnodes (inclusive) | ||
firstIndex int | ||
// last index of elements in this node subnodes (inclusive) | ||
lastIndex int | ||
} | ||
|
||
func (n *Node) GetIndexProofs(i int) []Proof { | ||
proofs := make([]Proof, 0) | ||
|
||
if n.left != nil && i >= n.left.firstIndex && i <= n.left.lastIndex { | ||
proofs = n.left.GetIndexProofs(i) | ||
proofs = append(proofs, Proof{hash: n.right.hash, leftSide: false}) | ||
} | ||
|
||
if n.right != nil && i >= n.right.firstIndex && i <= n.right.lastIndex { | ||
proofs = n.right.GetIndexProofs(i) | ||
proofs = append(proofs, Proof{hash: n.left.hash, leftSide: true}) | ||
} | ||
|
||
return proofs | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,23 +1,20 @@ | ||
package merkle | ||
|
||
import "crypto/sha256" | ||
import ( | ||
"hash" | ||
) | ||
|
||
type Proof struct { | ||
left bool // where proof should be placed for concat with hash (left or right) | ||
hash []byte | ||
leftSide bool // where proof should be placed to sum with hash (left or right side) | ||
hash []byte | ||
} | ||
|
||
// calculate sum hash | ||
func (p *Proof) ConcatWith(hash []byte) []byte { | ||
h := sha256.New() | ||
func (p *Proof) SumWith(hashF hash.Hash, hash []byte) []byte { | ||
|
||
if p.left { | ||
h.Write(p.hash) | ||
h.Write(hash) | ||
if p.leftSide { | ||
return sum(hashF, p.hash, hash) | ||
} else { | ||
h.Write(hash) | ||
h.Write(p.hash) | ||
return sum(hashF, hash, p.hash) | ||
} | ||
|
||
return h.Sum(nil) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
package merkle | ||
|
||
import "hash" | ||
|
||
// subtrees always should have power of 2 number of elements. | ||
// tree could contain few of subtrees. | ||
// root hash calculates from right to left by summing subtree roots hashes. | ||
type Subtree struct { | ||
root *Node // root node | ||
|
||
left *Subtree // left subtree from this one | ||
right *Subtree // right subtree from this one | ||
|
||
height int // height of subtree | ||
// hash function to hash sum nodes and hash data | ||
hashF hash.Hash | ||
} | ||
|
||
// get proofs for root of this subtree | ||
func (t *Subtree) GetRootProofs() []Proof { | ||
proofs := make([]Proof, 0) | ||
|
||
proofs = append(proofs, t.getRightSubtreesProof()...) | ||
proofs = append(proofs, t.getLeftSubtreesProof()...) | ||
|
||
return proofs | ||
} | ||
|
||
func (t *Subtree) getLeftSubtreesProof() []Proof { | ||
proofs := make([]Proof, 0) | ||
current := t.left | ||
for current != nil { | ||
proofs = append(proofs, Proof{hash: current.root.hash, leftSide: false}) | ||
current = current.left | ||
} | ||
return proofs | ||
} | ||
|
||
// right proof is only one cause we have to sum all right subtrees | ||
// we have to sum hashes from right to left | ||
func (t *Subtree) getRightSubtreesProof() []Proof { | ||
|
||
if t.right == nil { | ||
return make([]Proof, 0) | ||
} | ||
|
||
hashesToSum := make([][]byte, 0) | ||
|
||
rightTree := t.right | ||
for rightTree != nil { | ||
hashesToSum = append(hashesToSum, rightTree.root.hash) | ||
rightTree = rightTree.right | ||
} | ||
|
||
n := len(hashesToSum) - 1 | ||
proofHash := hashesToSum[n] | ||
for i := n - 1; i >= 0; i-- { | ||
proofHash = sum(t.hashF, proofHash, hashesToSum[i]) | ||
} | ||
|
||
return []Proof{{hash: proofHash, leftSide: true}} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.