Last active
July 30, 2022 15:57
-
-
Save ryzokuken/4b2e34c79eb00327402079af884027c4 to your computer and use it in GitHub Desktop.
TypeScript Merkle Tree Implementation
This file contains hidden or 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
const hash = require('easy-crypto/hash'); | |
class MerkleTreeNodeGeneric { | |
compare(node) { | |
return this.hash === node.hash; | |
} | |
} | |
class MerkleTreeChildNode extends MerkleTreeNodeGeneric { | |
constructor(data) { | |
super(); | |
this.data = data; | |
this.hash = hash.hash('sha256', JSON.stringify(data), 'utf-8', 'hex'); | |
} | |
} | |
class MerkleTreeNode extends MerkleTreeNodeGeneric { | |
constructor(leftChild, rightChild) { | |
super(); | |
this.leftChild = leftChild; | |
this.rightChild = rightChild; | |
this.hash = hash.hash('sha256', leftChild.hash + rightChild.hash, 'hex', 'hex'); | |
} | |
} | |
function generateLevel(nodes) { | |
const result = []; | |
while (nodes.length > 1) { | |
const first = nodes.shift(); | |
const second = nodes.shift(); | |
result.push(new MerkleTreeNode(first, second)); | |
} | |
if (nodes.length == 1) { | |
const last = nodes.shift(); | |
result.push(new MerkleTreeNode(last, undefined)); | |
} | |
return result; | |
} | |
class MerkleTree { | |
constructor(documents) { | |
let nodes = documents.map(data => new MerkleTreeChildNode(data)); | |
while (nodes.length > 1) { | |
nodes = generateLevel(nodes); | |
} | |
this.root = nodes[0]; | |
} | |
compare(tree) { | |
return this.root.compare(tree.root); | |
} | |
} | |
const first = new MerkleTree(['one', 'two', 'three', 'four']); | |
const second = new MerkleTree(['one', 'two', 'three', 'four']); | |
const third = new MerkleTree(['one', 'two', 'five', 'four']); | |
console.log(first.compare(second)); | |
console.log(first.compare(third)); |
This file contains hidden or 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
import * as hash from 'easy-crypto/hash'; | |
class MerkleTreeNodeGeneric<T> { | |
hash: string; | |
compare(node: MerkleTreeNodeGeneric<T>) { | |
return this.hash === node.hash; | |
} | |
} | |
class MerkleTreeChildNode<T> extends MerkleTreeNodeGeneric<T> { | |
hash: string; | |
constructor(public data: T) { | |
super(); | |
this.hash = hash.hash('sha256', JSON.stringify(data), 'utf-8', 'hex'); | |
} | |
} | |
class MerkleTreeNode<T> extends MerkleTreeNodeGeneric<T> { | |
hash: string; | |
constructor(public leftChild: MerkleTreeNodeGeneric<T>, public rightChild: MerkleTreeNodeGeneric<T>) { | |
super(); | |
this.hash = hash.hash('sha256', leftChild.hash + rightChild.hash, 'hex', 'hex'); | |
} | |
} | |
function generateLevel<T>(nodes: MerkleTreeNodeGeneric<T>[]) { | |
const result: MerkleTreeNodeGeneric<T>[] = []; | |
while (nodes.length > 1) { | |
const first = nodes.shift(); | |
const second = nodes.shift(); | |
result.push(new MerkleTreeNode<T>(first, second)); | |
} | |
if (nodes.length == 1) { | |
const last = nodes.shift(); | |
result.push(new MerkleTreeNode<T>(last, undefined)); | |
} | |
return result; | |
} | |
class MerkleTree<T> { | |
root: MerkleTreeNodeGeneric<T>; | |
constructor(documents: T[]) { | |
let nodes: MerkleTreeNodeGeneric<T>[] = documents.map(data => new MerkleTreeChildNode<T>(data)); | |
while (nodes.length > 1) { | |
nodes = generateLevel(nodes); | |
} | |
this.root = nodes[0]; | |
} | |
compare(tree: MerkleTree<T>) { | |
return this.root.compare(tree.root); | |
} | |
} | |
const first = new MerkleTree<string>(['one', 'two', 'three', 'four']); | |
const second = new MerkleTree<string>(['one', 'two', 'three', 'four']); | |
const third = new MerkleTree<string>(['one', 'two', 'five', 'four']); | |
console.log(first.compare(second)); | |
console.log(first.compare(third)); |
Whats the license on this? Can I use it in an LGPLv3 project?
Please feel free. Let me know if you'd like me to release this as a LGPLv3 licensed npm module.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Whats the license on this? Can I use it in an LGPLv3 project?