Skip to content

Commit

Permalink
start on js offchain
Browse files Browse the repository at this point in the history
  • Loading branch information
MicroProofs committed May 27, 2024
1 parent ac87b02 commit 74faf18
Show file tree
Hide file tree
Showing 6 changed files with 4,985 additions and 3 deletions.
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,7 @@ build/
# Added by cargo
/target

blocks.json
blocks.json

**/node_modules
**/babel.config.js
4 changes: 2 additions & 2 deletions aiken.lock
Original file line number Diff line number Diff line change
Expand Up @@ -24,5 +24,5 @@ requirements = []
source = "github"

[etags]
"aiken-lang/fuzz@main" = [{ secs_since_epoch = 1716767673, nanos_since_epoch = 838856000 }, "98cf81aa68f9ccf68bc5aba9be06d06cb1db6e8eff60b668ed5e8ddf3588206b"]
"aiken-lang/stdlib@main" = [{ secs_since_epoch = 1716767673, nanos_since_epoch = 632434000 }, "dfda6bc70aad760f7f836c0db06b07e0a398bb3667f4d944d7d7255d54a454af"]
"aiken-lang/fuzz@main" = [{ secs_since_epoch = 1716834372, nanos_since_epoch = 391046000 }, "98cf81aa68f9ccf68bc5aba9be06d06cb1db6e8eff60b668ed5e8ddf3588206b"]
"aiken-lang/stdlib@main" = [{ secs_since_epoch = 1716834372, nanos_since_epoch = 160697000 }, "dfda6bc70aad760f7f836c0db06b07e0a398bb3667f4d944d7d7255d54a454af"]
22 changes: 22 additions & 0 deletions offchain/index.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { Leaf, SparseMerkleTree } from ".";
import { Buffer } from "buffer";

test("Test 1", () => {
const x = new SparseMerkleTree();

console.log(x.leftChild.key.toString(), x.rightChild.key.toString());

console.log(
x.leftChild instanceof Leaf
? Buffer.from(x.leftChild.leafHash).toString("hex")
: "Branch"
);
console.log(
x.rightChild instanceof Leaf
? Buffer.from(x.rightChild.leafHash).toString("hex")
: "Branch"
);

console.log(x);
console.log("Root Hash", Buffer.from(x.branchHash).toString("hex"));
});
139 changes: 139 additions & 0 deletions offchain/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
import { blake2b } from "blakejs";
import { BitSet } from "bitSet";
import { Buffer } from "buffer";

const message = new TextEncoder().encode("apple (0)");
const leafBytes = new Uint8Array(Buffer.from("0deeffaad07783", "hex"));

export class Leaf {
key: BitSet;
value: Uint8Array;
leafHash: Uint8Array;

constructor(value: String | Buffer) {
const bufferValue: Uint8Array =
value instanceof String
? new TextEncoder().encode(value.toString())
: new Uint8Array(value);

this.key = new BitSet(blake2b(bufferValue, undefined, 32));

this.value = bufferValue;

this.leafHash = blake2b(
Buffer.concat([leafBytes, blake2b(bufferValue, undefined, 32)]),
undefined,
32
);
}

static boundaryLeaf(isMin: boolean) {
if (isMin) {
let x = new Leaf(Buffer.from("00", "hex"));

x.key.clear(0, 256);

x.leafHash = blake2b(
Buffer.concat([leafBytes, new Uint8Array(32).fill(0)]),
undefined,
32
);

return x;
} else {
let x = new Leaf(Buffer.from("00", "hex"));

x.key.setRange(0, 255, 1);

x.leafHash = blake2b(
Buffer.concat([leafBytes, new Uint8Array(32).fill(255)]),
undefined,
32
);

return x;
}
}
}

export class Branch {
key: BitSet;
branchHash: Uint8Array;
leftChild: Leaf | Branch;
rightChild: Leaf | Branch;
height: number;

constructor(leftChild: Leaf | Branch, rightChild: Leaf | Branch) {
this.leftChild = leftChild;
this.rightChild = rightChild;

let leftKey = leftChild.key.clone();
let rightKey = rightChild.key.clone();
let currentHeight = -1;

if (leftChild instanceof Leaf) {
const heightDiff = rightChild instanceof Leaf ? 0 : rightChild.height + 1;

leftKey = leftKey.slice(heightDiff);
} else if (rightChild instanceof Leaf) {
const heightDiff = leftChild instanceof Leaf ? 0 : leftChild.height + 1;

rightKey = rightKey.slice(heightDiff);
} else {
currentHeight = Math.max(leftChild.height, rightChild.height);
if (leftChild.height > rightChild.height) {
leftKey = leftKey.slice(leftChild.height - rightChild.height);
} else {
rightKey = rightKey.slice(rightChild.height - leftChild.height);
}
}

while (!leftKey.equals(rightKey)) {
leftKey = leftKey.slice(1);
rightKey = rightKey.slice(1);
currentHeight++;

console.log(leftKey.toString(), rightKey.toString(), currentHeight);
}

this.key = leftKey;
this.height = currentHeight;

if (leftChild instanceof Leaf) {
this.branchHash = blake2b(
Buffer.concat([
leftChild.leafHash,
new Uint8Array(1).fill(currentHeight),
rightChild instanceof Leaf
? rightChild.leafHash
: rightChild.branchHash,
]),
undefined,
32
);
} else {
this.branchHash = blake2b(
Buffer.concat([
leftChild.branchHash,
new Uint8Array(1).fill(currentHeight),
rightChild instanceof Leaf
? rightChild.leafHash
: rightChild.branchHash,
]),
undefined,
32
);
}
}
}

export class SparseMerkleTree extends Branch {
leaves: Map<Uint8Array, Leaf>;

constructor() {
const leftChild = Leaf.boundaryLeaf(true);
const rightChild = Leaf.boundaryLeaf(false);
super(leftChild, rightChild);
this.leaves = new Map();
}
}
25 changes: 25 additions & 0 deletions offchain/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
{
"name": "sparse-merkle-tree",
"version": "0.0.1",
"description": "",
"main": "index.js",
"scripts": {
"test": "jest"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"bitset": "^5.1.1",
"blakejs": "^1.2.1"
},
"devDependencies": {
"jest": "^29.7.0",
"@babel/core": "^7.24.6",
"@babel/preset-env": "^7.24.6",
"@babel/preset-typescript": "^7.24.6",
"@types/jest": "^29.5.12",
"@types/node": "^20.12.12",
"babel-jest": "^29.7.0"
}
}
Loading

0 comments on commit 74faf18

Please sign in to comment.