add tests for edge cases

This commit is contained in:
ashpect
2024-07-28 12:25:29 +05:30
parent 2babb2da02
commit 48c45ef9e0
7 changed files with 351 additions and 111 deletions

View File

@@ -182,26 +182,25 @@ export function generateCircuitInputsOfac(
const namedob_leaf = getNameDobLeaf(mrz_bytes.slice(10,49), mrz_bytes.slice(62, 68)) // [57-62] + 5 shift
const name_leaf = getNameLeaf(mrz_bytes.slice(10,49)) // [6-44] + 5 shift
let root, depth, closestleaf, indices, siblings, membership;
let root, depth, closestleaf, indices, siblings, pathToMatch;
if(proofLevel == 3){
({root, depth, closestleaf, indices, siblings, membership} = generateSMTProof(sparsemerkletree, passport_leaf));
({root, depth, closestleaf, indices, siblings, pathToMatch} = generateSMTProof(sparsemerkletree, passport_leaf));
} else if(proofLevel == 2){
({root, depth, closestleaf, indices, siblings, membership} = generateSMTProof(sparsemerkletree, namedob_leaf));
({root, depth, closestleaf, indices, siblings, pathToMatch} = generateSMTProof(sparsemerkletree, namedob_leaf));
} else if (proofLevel == 1){
({root, depth, closestleaf, indices, siblings, membership} = generateSMTProof(sparsemerkletree, name_leaf));
({root, depth, closestleaf, indices, siblings, pathToMatch} = generateSMTProof(sparsemerkletree, name_leaf));
} else {
throw new Error("Invalid proof level")
}
const exists = membership ? 1 : 0;
return {
...finalResult,
leaf_value: [BigInt(closestleaf).toString()],
closest_leaf: [BigInt(closestleaf).toString()],
smt_root: [BigInt(root).toString()],
smt_size: [BigInt(depth).toString()],
smt_path : indices.map(index => BigInt(index).toString()),
smt_siblings: siblings.map(index => BigInt(index).toString()),
membership: [BigInt(exists).toString()],
path_to_match: pathToMatch.map(index => BigInt(index).toString())
};
}

View File

@@ -3,7 +3,7 @@ import { sha256 } from 'js-sha256';
import { sha1 } from 'js-sha1';
import { sha384 } from 'js-sha512';
import { SMT } from '@ashpect/smt';
import { poseidon2, poseidon3 } from 'poseidon-lite';
import { poseidon3 } from 'poseidon-lite';
export function formatMrz(mrz: string) {
const mrzCharcodes = [...mrz].map(char => char.charCodeAt(0));
@@ -303,7 +303,7 @@ export function packBytes(unpacked) {
export function generateSMTProof(smt: SMT, leaf: bigint) {
const {entry, matchingEntry, siblings, root, membership} = smt.createProof(leaf);
const depth = siblings.length
let closestleaf;
if (!matchingEntry){ // we got the 0 leaf or membership
// then check if entry[1] exists
@@ -317,14 +317,14 @@ export function generateSMTProof(smt: SMT, leaf: bigint) {
} else {
closestleaf = poseidon3(matchingEntry); // actual closest
}
const bits = entry[0].toString(2).slice(-depth);
const binary = entry[0].toString(2)
const bits = binary.slice(-depth);
let indices = bits.padEnd(256, "0").split("").map(Number)
siblings.reverse()
const pathToMatch = num2Bits(256,BigInt(entry[0])) //no need to pad actually as poseidon hashes are 256 onli
while(indices.length < 256) indices.push(0);
while(siblings.length < 256) siblings.push(BigInt(0));
// get to 256 for computation in circuit
// // CALCULATED ROOT FOR TESTING -- // Useful for debugging hence leaving as comments
// closestleaf, depth, siblings, indices, root : needed
@@ -345,7 +345,7 @@ export function generateSMTProof(smt: SMT, leaf: bigint) {
closestleaf,
indices,
siblings,
membership,
pathToMatch
};
}
@@ -387,3 +387,27 @@ export function hexToBin(n: string): string {
}
return bin
}
export function num2Bits(n: number, inValue: bigint): bigint[] {
const out: bigint[] = new Array(n).fill(BigInt(0));
let lc1: bigint = BigInt(0);
let e2: bigint = BigInt(1);
for (let i = 0; i < n; i++) {
out[i] = (inValue >> BigInt(i)) & BigInt(1);
if (out[i] !== BigInt(0) && out[i] !== BigInt(1)) {
throw new Error("Bit value is not binary.");
}
lc1 += out[i] * e2;
e2 = e2 << BigInt(1);
}
if (lc1 !== inValue) {
throw new Error("Reconstructed value does not match the input.");
}
return out;
}