Skip to content

Commit

Permalink
add another test
Browse files Browse the repository at this point in the history
  • Loading branch information
MicroProofs committed May 31, 2024
1 parent 25d9c42 commit 13f0303
Show file tree
Hide file tree
Showing 3 changed files with 174 additions and 20 deletions.
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 = 1716834372, nanos_since_epoch = 391046000 }, "98cf81aa68f9ccf68bc5aba9be06d06cb1db6e8eff60b668ed5e8ddf3588206b"]
"aiken-lang/stdlib@main" = [{ secs_since_epoch = 1716834372, nanos_since_epoch = 160697000 }, "dfda6bc70aad760f7f836c0db06b07e0a398bb3667f4d944d7d7255d54a454af"]
"aiken-lang/fuzz@main" = [{ secs_since_epoch = 1717167992, nanos_since_epoch = 648648000 }, "98cf81aa68f9ccf68bc5aba9be06d06cb1db6e8eff60b668ed5e8ddf3588206b"]
"aiken-lang/stdlib@main" = [{ secs_since_epoch = 1717167992, nanos_since_epoch = 410365000 }, "dfda6bc70aad760f7f836c0db06b07e0a398bb3667f4d944d7d7255d54a454af"]
61 changes: 55 additions & 6 deletions offchain/src/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { Buffer } from "buffer";

import { SparseMerkleTree } from "./index.js";

test("Test 1", () => {
test("Test Insert", () => {
const x = new SparseMerkleTree();
let rootList = [x.branchHash];
const expectedList = [
Expand Down Expand Up @@ -75,7 +75,7 @@ test("Test 1", () => {
);
});

test("Test 2", () => {
test("Test Modification Proof", () => {
const x = new SparseMerkleTree();
let rootList: Uint8Array[] = [];
const expectedList: string[] = [];
Expand All @@ -92,13 +92,62 @@ test("Test 2", () => {
x.insert("fig (0)");
x.insert("grape (110606)");

const thing1 = x.merkleProof("grape (110606)");
const other = x.modificationProof("grape (110606)");

console.log(thing1.toString(), "\n\n");
console.log(other.toString(), "\n\n");

x.insert("grapefruit (0)");

const thing = x.merkleProof("grapefruit (0)");
const expected = {
startingSide: "left",
remainingProofs: [
[
"26363294ff627e13438ecc429926a7cb64686944ec0587128338e3b447dc30e5",
255,
"right",
],
],
leftLeaf:
"3378b5c960257ffe7c3e86d00563739bdf7db730e10732f6b943a4c1802fd05e",
rightLeaf:
"55d5551e8e1323d35afe53cf8698867c9de9a408e97ee968dc8414d527cc719c",
leftProofs: [],
rightProofs: [
["0bca11bb74090bc698bc7b811c23e87d97744b10c16f2c7d5e23d82bd5f41bea", 253],
],
continuingSideProofs: [
["3d7b9d20ff5e977c69307d9d264fe6b36cd0fc08b390578b09d33a9f044d77dd", 253],
],
intersectingHeight: 251,
leftRightHeight: 254,
};

const actual = x.modificationProof("grapefruit (0)");

console.log(actual.toString());

expect(actual.toString()).toStrictEqual(JSON.stringify(expected));
});

test("Test Member Proof", () => {
const x = new SparseMerkleTree();
let rootList: Uint8Array[] = [];
const expectedList: string[] = [];

x.insert("apple (0)");
x.insert("apricot (0)");
x.insert("banana (328)");
x.insert("blackberry (0)");
x.insert("blueberry (92383)");
x.insert("cherry (0)");
x.insert("coconut (0)");
x.insert("cranberry (0)");
x.insert("durian (0)");
x.insert("fig (0)");
x.insert("grape (110606)");
x.insert("grapefruit (0)");

const thing = x.memberProof("grapefruit (0)");

console.log(thing.toString());
console.log(thing);
});
129 changes: 117 additions & 12 deletions offchain/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ export class Leaf {
}
}

doMerkeProof(_key: BitSet, _mutProof: MerkleProof): MerkleProof {
doModificationProof(_key: BitSet, _mutProof: MerkleProof): MerkleProof {
throw new Error("Not possible");
}

Expand All @@ -149,6 +149,10 @@ export class Leaf {
mutProof.leftLeaf = blake2b(this.value, undefined, 32);
}

doMemberProof(_key: BitSet): [Uint8Array, number, Side][] {
throw new Error("Not possible");
}

static boundaryLeaf(isMin: boolean) {
if (isMin) {
let x = new Leaf(Buffer.from("00", "hex"));
Expand Down Expand Up @@ -365,7 +369,7 @@ export class Branch {
}
}

doMerkeProof(key: BitSet, mutProof: MerkleProof) {
doModificationProof(key: BitSet, mutProof: MerkleProof) {
let leftHeight = this.height - 1;

if (this.leftChild instanceof Leaf) {
Expand Down Expand Up @@ -432,25 +436,26 @@ export class Branch {
}
}

if (key.equals(this.leftChild.key)) {
if (key.equals(this.rightChild.key)) {
mutProof.intersectingHeight = this.height;
mutProof.startingSide = "left";
this.leftChild.traverseRight(mutProof);
return;
} else if (key.equals(this.leftChild.key)) {
mutProof.intersectingHeight = this.height;
mutProof.startingSide = "right";
this.rightChild.traverseLeft(mutProof);

return;
} else if (key.equals(this.rightChild.key)) {
mutProof.intersectingHeight = this.height;
mutProof.startingSide = "left";
this.leftChild.traverseRight(mutProof);
return;
} else if (leftHeight >= 0 && rightHeight < 0) {
this.leftChild.doMerkeProof(key, mutProof);
this.leftChild.doModificationProof(key, mutProof);

if (
mutProof.startingSide === "left" &&
typeof mutProof.rightLeaf === "undefined"
) {
this.rightChild.traverseLeft(mutProof);
mutProof.leftRightHeight = this.height;
} else if (
mutProof.startingSide === "right" &&
typeof mutProof.leftLeaf === "undefined"
Expand All @@ -468,13 +473,14 @@ export class Branch {
}
return;
} else if (leftHeight < 0 && rightHeight >= 0) {
this.rightChild.doMerkeProof(key, mutProof);
this.rightChild.doModificationProof(key, mutProof);

if (
mutProof.startingSide === "right" &&
typeof mutProof.leftLeaf === "undefined"
) {
this.leftChild.traverseRight(mutProof);
mutProof.leftRightHeight = this.height;
} else if (
mutProof.startingSide === "left" &&
typeof mutProof.rightLeaf === "undefined"
Expand Down Expand Up @@ -508,6 +514,92 @@ export class Branch {

mutProof.insertLeftProof(this.leftChild.getHash(), this.height);
}

doMemberProof(key: BitSet): [Uint8Array, number, Side][] {
let leftHeight = this.height - 1;

if (this.leftChild instanceof Leaf) {
while (leftHeight > -1) {
if (
key
.slice(leftHeight + 1)
.equals(this.leftChild.key.slice(leftHeight + 1))
) {
break;
}

leftHeight--;
}
} else {
while (leftHeight >= this.leftChild.height) {
if (
key
.slice(leftHeight + 1)
.equals(
this.leftChild.key.slice(leftHeight - this.leftChild.height)
)
) {
break;
}

leftHeight--;
}
if (leftHeight < this.leftChild.height) {
leftHeight = -1;
}
}

let rightHeight = this.height - 1;

if (this.rightChild instanceof Leaf) {
while (rightHeight > -1) {
if (
key
.slice(rightHeight + 1)
.equals(this.rightChild.key.slice(rightHeight + 1))
) {
break;
}

rightHeight--;
}
} else {
while (rightHeight >= this.rightChild.height) {
if (
key
.slice(rightHeight + 1)
.equals(
this.rightChild.key.slice(rightHeight - this.rightChild.height)
)
) {
break;
}

rightHeight--;
}
if (rightHeight < this.rightChild.height) {
rightHeight = -1;
}
}

if (key.equals(this.leftChild.key)) {
return [[this.rightChild.getHash(), this.height, "right"]];
} else if (key.equals(this.rightChild.key)) {
return [[this.leftChild.getHash(), this.height, "left"]];
} else if (leftHeight >= 0 && rightHeight < 0) {
return [
[this.rightChild.getHash(), this.height, "right"],
...this.leftChild.doMemberProof(key),
];
} else if (leftHeight < 0 && rightHeight >= 0) {
return [
[this.leftChild.getHash(), this.height, "left"],
...this.rightChild.doMemberProof(key),
];
} else {
throw new Error("Impossible");
}
}
}

export class SparseMerkleTree extends Branch {
Expand All @@ -533,7 +625,7 @@ export class SparseMerkleTree extends Branch {
super.doInsert(initialKey, value);
}

merkleProof(value: string | Buffer) {
modificationProof(value: string | Buffer) {
const bufferValue: Uint8Array =
typeof value == "string"
? new TextEncoder().encode(value)
Expand All @@ -545,8 +637,21 @@ export class SparseMerkleTree extends Branch {

let merkleProof = new MerkleProof();

super.doMerkeProof(initialKey, merkleProof);
super.doModificationProof(initialKey, merkleProof);

return merkleProof;
}

memberProof(value: string | Buffer) {
const bufferValue: Uint8Array =
typeof value == "string"
? new TextEncoder().encode(value)
: new Uint8Array(value);

const initialKey = new BitSet(
Buffer.from(blake2b(bufferValue, undefined, 32)).reverse()
);

return super.doMemberProof(initialKey).reverse();
}
}

0 comments on commit 13f0303

Please sign in to comment.