Skip to content

Commit

Permalink
Merge pull request #55 from 0xPolygonHermez/fix/storage-counter-on-de…
Browse files Browse the repository at this point in the history
…lete

Fix/storage counter on delete
  • Loading branch information
krlosMata committed Oct 3, 2022
2 parents 9ec4e23 + 16c68e0 commit fc1e1d4
Show file tree
Hide file tree
Showing 6 changed files with 238 additions and 6 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@
"license": "UNLICENSED",
"dependencies": {
"@0xpolygonhermez/zkasmcom": "https://github.com/0xPolygonHermez/zkasmcom.git#v0.4.0.0",
"@0xpolygonhermez/zkevm-commonjs": "https://github.com/0xpolygonhermez/zkevm-commonjs.git#v0.4.0.0",
"@0xpolygonhermez/zkevm-commonjs": "https://github.com/0xpolygonhermez/zkevm-commonjs.git#v0.4.0.1",
"@0xpolygonhermez/zkevm-rom": "https://github.com/0xpolygonhermez/zkevm-rom.git#v0.4.0.0-rc.1",
"chalk": "^3.0.0",
"circomlib": "^2.0.3",
Expand Down
11 changes: 10 additions & 1 deletion test/counters/storage.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,16 @@ describe("Test Storage Counters", async function () {

it("Verify Storage Zkasm Test", async () => {
await verifyZkasm("../zkasm/counters/storage.zkasm", true,
{ defines: {N: 2 ** 21},
{ defines: {N: 2 ** 16},
namespaces: ['Global', 'Main', 'Storage'],
verbose: true,
color: true,
disableUnusedError: true});
});

it("Verify Storage Zkasm Test (some delete edge cases)", async () => {
await verifyZkasm("../zkasm/counters/storage2.zkasm", true,
{ defines: {N: 2 ** 16},
namespaces: ['Global', 'Main', 'Rom', 'Byte4', 'Storage', 'PoseidonG'],
verbose: true,
color: true,
Expand Down
74 changes: 73 additions & 1 deletion test/sm/sm_storage/sm_storage_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,16 @@ describe("Test storage operations", async function () {
cmPols.Main.op5[index] = 0n;
cmPols.Main.op6[index] = 0n;
cmPols.Main.op7[index] = 0n;
cmPols.Main.incCounter[index] = 0n;
cmPols.Main.sWR[index] = 0n;
cmPols.Main.D0[index] = 0n;
cmPols.Main.D1[index] = 0n;
cmPols.Main.D2[index] = 0n;
cmPols.Main.D3[index] = 0n;
cmPols.Main.D4[index] = 0n;
cmPols.Main.D5[index] = 0n;
cmPols.Main.D6[index] = 0n;
cmPols.Main.D7[index] = 0n;
}

db = new MemDB(fr);
Expand All @@ -71,6 +81,59 @@ describe("Test storage operations", async function () {

async function smtSet (oldRoot, key, value) {
const r = await smt.set(oldRoot, key, value);
const index = plookUpIndex++;
cmPols.Main.sRD[index] = fr.zero;
cmPols.Main.sWR[index] = fr.e(1n);
cmPols.Main.SR0[index] = fr.e(oldRoot[0] & 0xFFFFFFFFn);
cmPols.Main.SR1[index] = fr.e(oldRoot[0] >> 32n);
cmPols.Main.SR2[index] = fr.e(oldRoot[1] & 0xFFFFFFFFn);
cmPols.Main.SR3[index] = fr.e(oldRoot[1] >> 32n);
cmPols.Main.SR4[index] = fr.e(oldRoot[2] & 0xFFFFFFFFn);
cmPols.Main.SR5[index] = fr.e(oldRoot[2] >> 32n);
cmPols.Main.SR6[index] = fr.e(oldRoot[3] & 0xFFFFFFFFn);
cmPols.Main.SR7[index] = fr.e(oldRoot[3] >> 32n);
cmPols.Main.D0[index] = value & 0xFFFFFFFFn;
value = value >> 32n;
cmPols.Main.D1[index] = value & 0xFFFFFFFFn;
value = value >> 32n;
cmPols.Main.D2[index] = value & 0xFFFFFFFFn;
value = value >> 32n;
cmPols.Main.D3[index] = value & 0xFFFFFFFFn;
value = value >> 32n;
cmPols.Main.D4[index] = value & 0xFFFFFFFFn;
value = value >> 32n;
cmPols.Main.D5[index] = value & 0xFFFFFFFFn;
value = value >> 32n;
cmPols.Main.D6[index] = value & 0xFFFFFFFFn;
value = value >> 32n;
cmPols.Main.D7[index] = value & 0xFFFFFFFFn;
value = value >> 32n;
cmPols.Main.sKey[0][index] = key[0];
cmPols.Main.sKey[1][index] = key[1];
cmPols.Main.sKey[2][index] = key[2];
cmPols.Main.sKey[3][index] = key[3];
cmPols.Main.op0[index] = fr.e(r.newRoot[0] & 0xFFFFFFFFn);
cmPols.Main.op1[index] = fr.e(r.newRoot[0] >> 32n);
cmPols.Main.op2[index] = fr.e(r.newRoot[1] & 0xFFFFFFFFn);
cmPols.Main.op3[index] = fr.e(r.newRoot[1] >> 32n);
cmPols.Main.op4[index] = fr.e(r.newRoot[2] & 0xFFFFFFFFn);
cmPols.Main.op5[index] = fr.e(r.newRoot[2] >> 32n);
cmPols.Main.op6[index] = fr.e(r.newRoot[3] & 0xFFFFFFFFn);
cmPols.Main.op7[index] = fr.e(r.newRoot[3] >> 32n);
cmPols.Main.incCounter = r.proofHashCounter;
/* console.log(index+' '+[
fr.e(cmPols.Main.SR0[index] + cmPols.Main.SR1[index] * 2n**32n),
fr.e(cmPols.Main.SR2[index] + cmPols.Main.SR3[index] * 2n**32n),
fr.e(cmPols.Main.SR4[index] + cmPols.Main.SR5[index] * 2n**32n),
fr.e(cmPols.Main.SR6[index] + cmPols.Main.SR7[index] * 2n**32n),
cmPols.Main.sKey[0][index], cmPols.Main.sKey[1][index], cmPols.Main.sKey[2][index], cmPols.Main.sKey[3][index],
cmPols.Main.D0[index], cmPols.Main.D1[index], cmPols.Main.D2[index], cmPols.Main.D3[index],
cmPols.Main.D4[index], cmPols.Main.D5[index], cmPols.Main.D6[index], cmPols.Main.D7[index],
fr.e(cmPols.Main.op0[index] + cmPols.Main.op1[index] * 2n**32n),
fr.e(cmPols.Main.op2[index] + cmPols.Main.op3[index] * 2n**32n),
fr.e(cmPols.Main.op4[index] + cmPols.Main.op5[index] * 2n**32n),
fr.e(cmPols.Main.op6[index] + cmPols.Main.op7[index] * 2n**32n),
cmPols.Main.incCounter].join(','));*/
required.Storage.push({bIsSet: true,
setResult: {
oldRoot: [...r.oldRoot],
Expand All @@ -90,9 +153,9 @@ describe("Test storage operations", async function () {

async function smtGet (root, key) {
const r = await smt.get(root, key);
console.log(['r', r, root, key]);
const index = plookUpIndex++;
cmPols.Main.sRD[index] = fr.e(1n);
cmPols.Main.sWR[index] = fr.zero;
cmPols.Main.SR0[index] = fr.e(r.root[0] & 0xFFFFFFFFn);
cmPols.Main.SR1[index] = fr.e(r.root[0] >> 32n);
cmPols.Main.SR2[index] = fr.e(r.root[1] & 0xFFFFFFFFn);
Expand All @@ -101,6 +164,14 @@ describe("Test storage operations", async function () {
cmPols.Main.SR5[index] = fr.e(r.root[2] >> 32n);
cmPols.Main.SR6[index] = fr.e(r.root[3] & 0xFFFFFFFFn);
cmPols.Main.SR7[index] = fr.e(r.root[3] >> 32n);
cmPols.Main.D0[index] = fr.zero;
cmPols.Main.D1[index] = fr.zero;
cmPols.Main.D2[index] = fr.zero;
cmPols.Main.D3[index] = fr.zero;
cmPols.Main.D4[index] = fr.zero;
cmPols.Main.D5[index] = fr.zero;
cmPols.Main.D6[index] = fr.zero;
cmPols.Main.D7[index] = fr.zero;
cmPols.Main.sKey[0][index] = key[0];
cmPols.Main.sKey[1][index] = key[1];
cmPols.Main.sKey[2][index] = key[2];
Expand All @@ -122,6 +193,7 @@ describe("Test storage operations", async function () {
rvalue = rvalue >> 32n;
cmPols.Main.op7[index] = rvalue & 0xFFFFFFFFn;
rvalue = rvalue >> 32n;
cmPols.Main.incCounter = r.proofHashCounter;
required.Storage.push({bIsSet: false,
getResult: {
root: [...r.root],
Expand Down
27 changes: 24 additions & 3 deletions test/sm/sm_storage/storage_main.pil
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,41 @@ include "../../../pil/storage.pil";

namespace Main(%N);

pol commit sRD;
pol commit sRD, sWR;
pol commit SR0, SR1, SR2, SR3, SR4, SR5, SR6, SR7;
pol commit D0, D1, D2, D3, D4, D5, D6, D7;
pol commit sKey[4];
pol commit op0, op1, op2, op3, op4, op5, op6, op7;
pol commit incCounter;

sRD {
SR0 + 2**32*SR1, SR2 + 2**32*SR3, SR4 + 2**32*SR5, SR6 + 2**32*SR7,
sKey[0], sKey[1], sKey[2], sKey[3],
op0, op1, op2, op3,
op4, op5, op6, op7
op4, op5, op6, op7,
incCounter
} in
Storage.iLatchGet {
Storage.oldRoot0, Storage.oldRoot1, Storage.oldRoot2, Storage.oldRoot3,
Storage.rkey0, Storage.rkey1, Storage.rkey2, Storage.rkey3,
Storage.valueLow0, Storage.valueLow1, Storage.valueLow2, Storage.valueLow3,
Storage.valueHigh0, Storage.valueHigh1, Storage.valueHigh2, Storage.valueHigh3
Storage.valueHigh0, Storage.valueHigh1, Storage.valueHigh2, Storage.valueHigh3,
incCounter
};

sWR {
SR0 + 2**32*SR1, SR2 + 2**32*SR3, SR4 + 2**32*SR5, SR6 + 2**32*SR7,
sKey[0], sKey[1], sKey[2], sKey[3],
D0, D1, D2, D3,
D4, D5, D6, D7,
op0 + 2**32*op1, op2 + 2**32*op3, op4 + 2**32*op5, op6 + 2**32*op7,
incCounter
} in
Storage.iLatchSet {
Storage.oldRoot0, Storage.oldRoot1, Storage.oldRoot2, Storage.oldRoot3,
Storage.rkey0, Storage.rkey1, Storage.rkey2, Storage.rkey3,
Storage.valueLow0, Storage.valueLow1, Storage.valueLow2, Storage.valueLow3,
Storage.valueHigh0, Storage.valueHigh1, Storage.valueHigh2, Storage.valueHigh3,
Storage.newRoot0, Storage.newRoot1, Storage.newRoot2, Storage.newRoot3,
Storage.incCounter
};
66 changes: 66 additions & 0 deletions test/zkasm/counters/storage2.zkasm
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
; key bits with A,B = 0 C = #
CONST %_0000101 = 8 ; 0000101....1010 #8
CONST %_0000111 = 4 ; 0000111....0001 #4
CONST %_0010001 = 13 ; 0010001....0111 #13
CONST %_0011010 = 1 ; 0011010....1110 #1
CONST %_0011101 = 5 ; 0011101....0001 #5
CONST %_0100101 = 7 ; 0100101....0110 #7
CONST %_0101011 = 10 ; 0101011....1001 #10
CONST %_0110101 = 3 ; 0110101....0010 #3
CONST %_0110110 = 9 ; 0110110....0110 #9
CONST %_0111001 = 6 ; 0111001....0000 #6
CONST %_1010110 = 15 ; 1010110....0101 #15
CONST %_1010111 = 14 ; 1010111....1101 #14
CONST %_1100011 = 12 ; 1100011....1010 #12
CONST %_1101000 = 0 ; 1101000....0010 #0
CONST %_1101010 = 2 ; 1101010....1001 #2
CONST %_1111001 = 11 ; 1111001....0110 #11

start:

STEP => A
0 :ASSERT

; to verify that there are no correlations between counters
0 => A
CNT_ARITH :ASSERT
CNT_BINARY :ASSERT
CNT_KECCAK_F: ASSERT
CNT_MEM_ALIGN :ASSERT
CNT_POSEIDON_G :ASSERT
CNT_PADDING_PG :ASSERT

0 => SR

%_1111001 => A
0x10n => D
$ => SR :SSTORE

%_1100011 => A
0x20n => D
$ => SR :SSTORE

%_1101000 => A
0x40n => D
$ => SR :SSTORE

%_1111001 => A
0n => D
$ => SR :SSTORE

%_1101000 => A
0n => D
$ => SR :SSTORE

%_1100011 => A
0n => D
$ => SR :SSTORE

end:
0 => A,B,C,D,E,CTX, SP, PC, GAS, MAXMEM, SR

finalWait:
${beforeLast()} : JMPN(finalWait)

: JMP(start)
opINVALID:
64 changes: 64 additions & 0 deletions tools/gen_store_keys.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
const fs = require("fs")
const { Scalar } = require('ffjavascript');
const buildPoseidon = require("@0xpolygonhermez/zkevm-commonjs").getPoseidon;

const argv = require("yargs")
.usage("node gen_store_keys.js [-c <count>] [-o <output>]")
.help('h')
.alias("o", "output")
.alias("c", "count")
.argv;

async function main(){
const output = typeof(argv.output) === "string" ? argv.output.trim() : "-";
const count = typeof(argv.count) === "number" ? argv.count : 100;

const poseidon = await buildPoseidon();
const F = poseidon.F;

// set A, B = 0
const A012345B01 = [F.zero, F.zero, F.zero, F.zero, F.zero, F.zero, F.zero, F.zero];
let hashes = [];
for (let i = 0; i < count; ++i) {
const C = [i, F.zero, F.zero, F.zero, F.zero, F.zero, F.zero, F.zero];

const keyI = poseidon(A012345B01); // Kin0
const key = poseidon(C, keyI); // Kin1
hashes.push(splitKey(key).join('') + ' #'+i);
}
hashes.sort();
let maxDepth = 0;
for (let i = 1; i < count; ++i) {
const depth = [...hashes[i]].findIndex((bit, index) => bit !== hashes[i-1][index]);
maxDepth = depth > maxDepth ? depth : maxDepth;
}
const content = hashes.join("\n") + "\n";
if (output == '-') {
console.log(content);
} else {
fs.writeFileSync(output, content , "utf8");
}
console.log('max depth:' + maxDepth);


function splitKey(k) {
const res = [];
const auxk = [F.toObject(k[0]), F.toObject(k[1]), F.toObject(k[2]), F.toObject(k[3])];
for (let i = 0; i < 64; i++) {
for (let j = 0; j < 4; j++) {
res.push(Scalar.toNumber(Scalar.band(auxk[j], Scalar.e(1))));
auxk[j] = Scalar.shr(auxk[j], 1);
}
}

return res;
}
}

main().then(()=> {
process.exit(0);
}, (err) => {
console.log(err.message);
console.log(err.stack);
process.exit(1);
});

0 comments on commit fc1e1d4

Please sign in to comment.