Skip to content

Commit

Permalink
move utils to Hash
Browse files Browse the repository at this point in the history
  • Loading branch information
vmidyllic committed Oct 19, 2023
1 parent 7d31a05 commit 9791ba0
Show file tree
Hide file tree
Showing 4 changed files with 56 additions and 55 deletions.
61 changes: 31 additions & 30 deletions src/lib/hash/hash.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,14 +57,27 @@ export class Hash implements IHash {

static fromString(s: string): Hash {
try {
return newHashFromBigInt(BigInt(s))
return Hash.fromBigInt(BigInt(s));
}
catch (e) {
const deserializedHash = JSON.parse(s);
const bytes = Uint8Array.from(Object.values(deserializedHash.bytes));
return new Hash(bytes);
}
}
static fromBigInt(i: bigint):Hash {
if (!checkBigIntInField(i)) {
throw 'NewBigIntFromHashBytes: Value not inside the Finite Field';
}

const bytes = bigIntToUINT8Array(i);

return new Hash(swapEndianness(bytes));
}

static fromHex(h: string): Hash {
return new Hash(Hex.decodeString(h));
}

toJSON() {
return this.string();
Expand All @@ -73,50 +86,38 @@ export class Hash implements IHash {

export const ZERO_HASH = new Hash();

// returned bytes endianess will be big-endian
/**
* @deprecated The method should not be used and will be removed in the next major version,
* please use Hash.fromBigInt instead
*/
export const newHashFromBigInt = (bigNum: bigint): Hash => {
if (!checkBigIntInField(bigNum)) {
throw 'NewBigIntFromHashBytes: Value not inside the Finite Field';
}

const bytes = bigIntToUINT8Array(bigNum);

const hash = new Hash();
hash.value = bytes;
return hash;
return Hash.fromBigInt(bigNum);
};

/**
* @deprecated The method should not be used and will be removed in the next major version,
* please use Hash.fromBigInt instead
*/
export const newHashFromHex = (h: string): Hash => {
if (!h) {
return ZERO_HASH;
}

// TODO: add in field check

const hash = new Hash();
hash.value = swapEndianness(Hex.decodeString(h));
return hash;
return Hash.fromHex(h)
};

// return object of class Hash from a decimal string
/**
* @deprecated The method should not be used and will be removed in the next major version,
* please use Hash.fromBigString instead
*/
export const newHashFromString = (decimalString: string): Hash => {
const bigNum = BigInt(decimalString);

if (!checkBigIntInField(bigNum)) {
throw 'NewBigIntFromHashBytes: Value not inside the Finite Field';
}

return newHashFromBigInt(bigNum);
return Hash.fromString(decimalString);
};

export const hashElems = (e: Array<bigint>): Hash => {
const hashBigInt = poseidon.hash(e);
return newHashFromBigInt(hashBigInt);
return Hash.fromBigInt(hashBigInt);
};

export const hashElemsKey = (k: bigint, e: Array<bigint>): Hash => {
const hashBigInt = poseidon.hash([...e, k]);
return newHashFromBigInt(hashBigInt);
return Hash.fromBigInt(hashBigInt);
};

export const circomSiblingsFromSiblings = (siblings: Siblings, levels: number): Siblings => {
Expand Down
28 changes: 14 additions & 14 deletions src/lib/merkletree/merkletree.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { ITreeStorage } from '../../types/storage';
import { Hash, ZERO_HASH, circomSiblingsFromSiblings, newHashFromBigInt } from '../hash/hash';
import { Hash, ZERO_HASH, circomSiblingsFromSiblings } from '../hash/hash';

import { Node } from '../../types';
import { NODE_TYPE_EMPTY, NODE_TYPE_LEAF, NODE_TYPE_MIDDLE } from '../../constants';
Expand Down Expand Up @@ -48,8 +48,8 @@ export class Merkletree {
}

this.#root = await this.root();
const kHash = newHashFromBigInt(k);
const vHash = newHashFromBigInt(v);
const kHash = Hash.fromBigInt(k);
const vHash = Hash.fromBigInt(v);

const newNodeLeaf = new NodeLeaf(kHash, vHash);
const path = getPath(this.maxLevels, kHash.value);
Expand Down Expand Up @@ -193,7 +193,7 @@ export class Merkletree {
}

async get(k: bigint): Promise<{ key: bigint; value: bigint; siblings: Siblings }> {
const kHash = newHashFromBigInt(k);
const kHash = Hash.fromBigInt(k);
const path = getPath(this.maxLevels, kHash.value);

let nextKey = await this.root();
Expand Down Expand Up @@ -254,8 +254,8 @@ export class Merkletree {
throw 'key not inside the finite field';
}

const kHash = newHashFromBigInt(k);
const vHash = newHashFromBigInt(v);
const kHash = Hash.fromBigInt(k);
const vHash = Hash.fromBigInt(v);

const path = getPath(this.maxLevels, kHash.value);

Expand Down Expand Up @@ -352,7 +352,7 @@ export class Merkletree {
throw ErrNotWritable;
}

const kHash = newHashFromBigInt(k);
const kHash = Hash.fromBigInt(k);
const path = getPath(this.maxLevels, kHash.value);

let nextKey = this.#root;
Expand Down Expand Up @@ -479,8 +479,8 @@ export class Merkletree {
cp.oldKey = ZERO_HASH;
cp.oldValue = ZERO_HASH;
}
cp.key = newHashFromBigInt(k);
cp.value = newHashFromBigInt(value);
cp.key = Hash.fromBigInt(k);
cp.value = Hash.fromBigInt(value);

if (proof.existence) {
cp.fnc = 0;
Expand All @@ -494,7 +494,7 @@ export class Merkletree {
async generateProof(k: bigint, rootKey?: Hash): Promise<{ proof: Proof; value: bigint }> {
let siblingKey: Hash;

const kHash = newHashFromBigInt(k);
const kHash = Hash.fromBigInt(k);
const path = getPath(this.maxLevels, kHash.value);
if (!rootKey) {
rootKey = await this.root();
Expand Down Expand Up @@ -585,8 +585,8 @@ export class Merkletree {
throw 'key/value undefined';
}

cp.oldKey = newHashFromBigInt(key);
cp.oldValue = newHashFromBigInt(value);
cp.oldKey = Hash.fromBigInt(key);
cp.oldValue = Hash.fromBigInt(value);

if (bytesEqual(cp.oldKey.value, ZERO_HASH.value)) {
cp.isOld0 = true;
Expand All @@ -595,8 +595,8 @@ export class Merkletree {
cp.siblings = circomSiblingsFromSiblings(siblings, this.maxLevels);
await this.add(k, v);

cp.newKey = newHashFromBigInt(k);
cp.newValue = newHashFromBigInt(v);
cp.newKey = Hash.fromBigInt(k);
cp.newValue = Hash.fromBigInt(v);
cp.newRoot = await this.root();

return cp;
Expand Down
6 changes: 3 additions & 3 deletions src/lib/merkletree/proof.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { NodeAux, Siblings } from '../../types/merkletree';
import { ELEM_BYTES_LEN, NOT_EMPTIES_LEN, PROOF_FLAG_LEN } from '../../constants';
import { bytesEqual, getPath, setBitBigEndian, siblings2Bytes, testBitBigEndian } from '../utils';
import { Hash, ZERO_HASH, newHashFromBigInt } from '../hash/hash';
import { Hash, ZERO_HASH } from '../hash/hash';
import { NodeMiddle } from '../node/node';
import { leafKey } from '../utils/node';
import { ErrNodeAuxNonExistAgainstHIndex } from '../errors/proof';
Expand Down Expand Up @@ -150,8 +150,8 @@ export const verifyProof = async (
};

export const rootFromProof = async (proof: Proof, k: bigint, v: bigint): Promise<Hash> => {
const kHash = newHashFromBigInt(k);
const vHash = newHashFromBigInt(v);
const kHash = Hash.fromBigInt(k);
const vHash = Hash.fromBigInt(v);
let midKey: Hash;

if (proof.existence) {
Expand Down
16 changes: 8 additions & 8 deletions tests/full.test.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { UseStore, createStore, clear } from 'idb-keyval';
import { HASH_BYTES_LENGTH, MAX_NUM_IN_FIELD } from '../src/constants';
import { NodeLeaf, NodeMiddle } from '../src/lib/node/node';
import { NodeMiddle } from '../src/lib/node/node';
import { InMemoryDB, LocalStorageDB, IndexedDBStorage } from '../src/lib/db';
import { bigIntToUINT8Array, bigint2Array, bytes2BinaryString, bytes2Hex, bytesEqual, newBigIntFromBytes, str2Bytes } from '../src/lib/utils';
import { Hash, ZERO_HASH, newHashFromBigInt } from '../src/lib/hash/hash';
import { bigIntToUINT8Array, bytes2Hex, bytesEqual, str2Bytes } from '../src/lib/utils';
import { Hash, ZERO_HASH } from '../src/lib/hash/hash';
import { Merkletree, Proof, siblignsFroomProof, verifyProof } from '../src/lib/merkletree';
import { ErrEntryIndexAlreadyExists, ErrKeyNotFound, ErrReachedMaxLevel } from '../src/lib/errors';

Expand All @@ -13,10 +13,7 @@ import { poseidon } from '@iden3/js-crypto';
import 'mock-local-storage';
import 'fake-indexeddb/auto';
import { Node } from '../src/types';
import { ffUtils } from '@iden3/js-crypto';
import { nodeValue } from '../src/lib/utils/node';

import {writeFileSync} from "fs"
enum TreeStorageType {
LocalStorageDB = 'localStorage',
InMemoryDB = 'memoryStorage',
Expand Down Expand Up @@ -351,8 +348,8 @@ for (let index = 0; index < storages.length; index++) {
expect(proof.existence).to.be.true;
proof.existence = false;
proof.nodeAux = {
key: newHashFromBigInt(BigInt('4')),
value: newHashFromBigInt(BigInt('4'))
key: Hash.fromBigInt(BigInt('4')),
value: Hash.fromBigInt(BigInt('4'))
};

expect(await verifyProof(await mt.root(), proof, BigInt('4'), BigInt('0'))).to.be.false;
Expand Down Expand Up @@ -694,6 +691,9 @@ for (let index = 0; index < storages.length; index++) {
expect(JSON.stringify(hash.bytes)).to.equal(JSON.stringify(bytes))
expect(hash.toJSON()).to.equal(hash2.bigInt().toString())
expect(hash.bytes).to.deep.equal(hash2.bytes);

expect(hash.hex()).to.equal(Hash.fromHex(hash2.hex()).hex())

});
it('test smt verifier', async () => {
const sto = getTreeStorage();
Expand Down

0 comments on commit 9791ba0

Please sign in to comment.