具体见:
Polygon zkEVM全局多项式Global.pil中包含3个constant多项式:
namespace Global(%N);
pol constant L1; // 1, 0, 0, 0, 0,
pol constant BYTE;
pol constant BYTE2;
这些全局constant多项式的基本赋值情况为:
module.exports.buildConstants = async function (pols) {
const F = new F1Field("0xFFFFFFFF00000001");
const N = pols.BYTE.length;
buidBYTE(pols.BYTE, F, N);
buidBYTE2(pols.BYTE2, F, N);
buildL1(pols.L1, F, N);
};
function buidBYTE2(pol, F, N) {
const m = 1<<16;
if (N<m) throw new Error("GLOBAL.BYTE does not fit");
for (let i=0; i<m; i++) {
pol[i] = BigInt(i);
}
for (let i=m; i<N; i++) {
pol[i] = 0n;
}
}
function buidBYTE(pol, F, N) {
if (N<256) throw new Error("GLOBAL.BYTE does not fit");
for (let i=0; i<256; i++) {
pol[i] = BigInt(i);
}
for (let i=256; i<N; i++) {
pol[i] = 0n;
}
}
function buildL1(pol, F, N) {
pol[0] = 1n;
for ( let i=1; i<N; i++) pol[i] = 0n;
}
以 N = 2 31 N=2^{31} N=231为例,这些全局常量多项式的具体赋值为:
index | L1 | BYTE | BYTE2 |
---|---|---|---|
0 | 1 | 0 | 0 |
1 | 0 | 1 | 1 |
2 | 0 | 2 | 2 |
3 | 0 | 3 | 3 |
⋮ \vdots ⋮ | ⋮ \vdots ⋮ | ⋮ \vdots ⋮ | ⋮ \vdots ⋮ |
254 | 0 | 254 | 254 |
255 | 0 | 255 | 255 |
256 | 0 | 0 | 256 |
257 | 0 | 0 | 257 |
⋮ \vdots ⋮ | ⋮ \vdots ⋮ | ⋮ \vdots ⋮ | ⋮ \vdots ⋮ |
2 16 − 1 2^{16}-1 216−1 | 0 | 0 | 2 16 − 1 2^{16}-1 216−1 |
2 16 2^{16} 216 | 0 | 0 | 0 |
2 16 + 1 2^{16}+1 216+1 | 0 | 0 | 0 |
⋮ \vdots ⋮ | ⋮ \vdots ⋮ | ⋮ \vdots ⋮ | ⋮ \vdots ⋮ |
2 21 − 1 2^{21}-1 221−1 | 0 | 0 | 0 |
main.pil中包含一个常量多项式STEP:【注意,在zkasm.js中,将STEP定义为只读寄存器。】
/// Constant Polynomials
pol constant STEP; // 0, 1, 2, 3, .......
相应的赋值为:
module.exports = async function (pols) {
const N = pols.STEP.length;
for ( let i=0; i<N; i++) {
pols.STEP[i] = BigInt(i);
}
}
以 N = 2 31 N=2^{31} N=231为例,该常量多项式的具体赋值为:
index | STEP |
---|---|
0 | 0 |
1 | 1 |
2 | 2 |
3 | 3 |
⋮ \vdots ⋮ | ⋮ \vdots ⋮ |
2 21 − 1 2^{21}-1 221−1 | 2 21 − 1 2^{21}-1 221−1 |
rom.pil中包含的常量多项式有:
namespace Rom(%N);
pol constant CONST0;
pol constant CONST1;
pol constant CONST2;
pol constant CONST3;
pol constant CONST4;
pol constant CONST5;
pol constant CONST6;
pol constant CONST7;
pol constant offset;
pol constant inA, inB, inC, inROTL_C, inD, inE, inSR, inFREE, inCTX, inSP, inPC, inGAS, inMAXMEM, inHASHPOS, inSTEP, inRR;
pol constant setA, setB, setC, setD, setE, setSR, setCTX, setSP, setPC, setGAS, setMAXMEM, setHASHPOS, JMP, JMPN, JMPC, setRR;
pol constant incStack, incCode;
pol constant isStack;
pol constant isCode;
pol constant isMem;
pol constant ind, indRR;
pol constant useCTX;
pol constant mOp, mWR;
pol constant sWR, sRD;
pol constant arith;
pol constant arithEq0;
pol constant arithEq1;
pol constant arithEq2;
pol constant arithEq3;
pol constant memAlign, memAlignWR, memAlignWR8;
pol constant hashK, hashKLen, hashKDigest;
pol constant hashP, hashPLen, hashPDigest;
pol constant bin;
pol constant binOpcode;
pol constant assert;
pol constant line;
不过,rom.pil中的常量多项式的值不是固定的,而是根据zkasm编译出的json文件来设定:
module.exports.buildConstants = async function buildConstants(pols, rom) {
const F = new F1Field("0xFFFFFFFF00000001");
const N = pols.inA.length;
const twoTo31 = Scalar.e(0x80000000);
const maxInt = 2147483647;
const minInt = -2147483648;
const maxUInt = 0xFFFFFFFF;
const minUInt = 0;
if (rom.program.length>N) throw new Error("Rom is too big for this N");
for (let i=0; i<rom.program.length; i++) {
if (rom.program[i].CONST) {
if (rom.program[i].CONSTL) throw new Error("Program mixed with long and short constants");
pols.CONST0[i] = rom.program[i].CONST ? F.e(rom.program[i].CONST) : F.zero;
pols.CONST1[i] = F.zero;
pols.CONST2[i] = F.zero;
pols.CONST3[i] = F.zero;
pols.CONST4[i] = F.zero;
pols.CONST5[i] = F.zero;
pols.CONST6[i] = F.zero;
pols.CONST7[i] = F.zero;
} else if (rom.program[i].CONSTL) {
[
pols.CONST0[i],
pols.CONST1[i],
pols.CONST2[i],
pols.CONST3[i],
pols.CONST4[i],
pols.CONST5[i],
pols.CONST6[i],
pols.CONST7[i],
] = scalar2fea(F, BigInt(rom.program[i].CONSTL));
} else {
pols.CONST0[i] = F.zero;
pols.CONST1[i] = F.zero;
pols.CONST2[i] = F.zero;
pols.CONST3[i] = F.zero;
pols.CONST4[i] = F.zero;
pols.CONST5[i] = F.zero;
pols.CONST6[i] = F.zero;
pols.CONST7[i] = F.zero;
}
pols.offset[i] = rom.program[i].offset ? BigInt(rom.program[i].offset) : 0n;
pols.inA[i] = rom.program[i].inA ? F.e(rom.program[i].inA) : F.zero;
pols.inB[i] = rom.program[i].inB ? F.e(rom.program[i].inB) : F.zero;
pols.inC[i] = rom.program[i].inC ? F.e(rom.program[i].inC) : F.zero;
pols.inD[i] = rom.program[i].inD ? F.e(rom.program[i].inD) : F.zero;
pols.inE[i] = rom.program[i].inE ? F.e(rom.program[i].inE) : F.zero;
pols.inSR[i] = rom.program[i].inSR ? F.e(rom.program[i].inSR) : F.zero;
pols.inCTX[i] = rom.program[i].inCTX ? F.e(rom.program[i].inCTX) : F.zero;
pols.inSP[i] = rom.program[i].inSP ? F.e(rom.program[i].inSP) : F.zero;
pols.inPC[i] = rom.program[i].inPC ? F.e(rom.program[i].inPC) : F.zero;
pols.inMAXMEM[i] = rom.program[i].inMAXMEM ? F.e(rom.program[i].inMAXMEM) : F.zero;
pols.inSTEP[i] = rom.program[i].inSTEP ? F.e(rom.program[i].inSTEP) : F.zero;
pols.inFREE[i] = rom.program[i].inFREE ? F.e(rom.program[i].inFREE) : F.zero;
pols.inGAS[i] = rom.program[i].inGAS ? F.e(rom.program[i].inGAS) : F.zero;
pols.inRR[i] = rom.program[i].inRR ? F.e(rom.program[i].inRR) : F.zero;
pols.inHASHPOS[i] = rom.program[i].inHASHPOS ? F.e(rom.program[i].inHASHPOS) : F.zero;
pols.inROTL_C[i] = rom.program[i].inROTL_C ? F.e(rom.program[i].inROTL_C) : F.zero;
pols.setA[i] = rom.program[i].setA ? 1n : 0n;
pols.setB[i] = rom.program[i].setB ? 1n : 0n;
pols.setC[i] = rom.program[i].setC ? 1n : 0n;
pols.setD[i] = rom.program[i].setD ? 1n : 0n;
pols.setE[i] = rom.program[i].setE ? 1n : 0n;
pols.setSR[i] = rom.program[i].setSR ? 1n : 0n;
pols.setCTX[i] = rom.program[i].setCTX ? 1n : 0n;
pols.setSP[i] = rom.program[i].setSP ? 1n : 0n;
pols.setPC[i] = rom.program[i].setPC ? 1n : 0n;
pols.setGAS[i] = rom.program[i].setGAS ? 1n : 0n;
pols.setMAXMEM[i] = rom.program[i].setMAXMEM ? 1n : 0n;
pols.setRR[i] = rom.program[i].setRR ? 1n : 0n;
pols.setHASHPOS[i] = rom.program[i].setHASHPOS ? 1n : 0n;
pols.JMP[i] = rom.program[i].JMP ? 1n : 0n;
pols.JMPC[i] = rom.program[i].JMPC ? 1n : 0n;
pols.JMPN[i] = rom.program[i].JMPN ? 1n : 0n;
pols.incStack[i] = rom.program[i].incStack ? BigInt(rom.program[i].incStack) : 0n;
pols.incCode[i] = rom.program[i].incCode ? BigInt(rom.program[i].incCode) : 0n;
pols.isStack[i] = rom.program[i].isStack ? 1n : 0n;
pols.isCode[i] = rom.program[i].isCode ? 1n : 0n;
pols.isMem[i] = rom.program[i].isMem ? 1n : 0n;
pols.ind[i] = rom.program[i].ind ? 1n : 0n;
pols.indRR[i] = rom.program[i].indRR ? 1n : 0n;
pols.useCTX[i] = rom.program[i].useCTX ? 1n : 0n;
pols.mOp[i] = rom.program[i].mOp ? 1n : 0n;
pols.mWR[i] = rom.program[i].mWR ? 1n : 0n;
pols.sRD[i] = rom.program[i].sRD ? 1n : 0n;
pols.sWR[i] = rom.program[i].sWR ? 1n : 0n;
pols.arith[i] = rom.program[i].arith ? 1n : 0n;
pols.arithEq0[i] = rom.program[i].arithEq0 ? 1n : 0n;
pols.arithEq1[i] = rom.program[i].arithEq1 ? 1n : 0n;
pols.arithEq2[i] = rom.program[i].arithEq2 ? 1n : 0n;
pols.arithEq3[i] = rom.program[i].arithEq3 ? 1n : 0n;
pols.memAlign[i] = rom.program[i].memAlign ? 1n : 0n;
pols.memAlignWR[i] = rom.program[i].memAlignWR ? 1n : 0n;
pols.memAlignWR8[i] = rom.program[i].memAlignWR8 ? 1n : 0n;
pols.hashK[i] = rom.program[i].hashK ? 1n : 0n;
pols.hashKLen[i] = rom.program[i].hashKLen ? 1n : 0n;
pols.hashKDigest[i] = rom.program[i].hashKDigest ? 1n : 0n;
pols.hashP[i] = rom.program[i].hashP ? 1n : 0n;
pols.hashPLen[i] = rom.program[i].hashPLen ? 1n : 0n;
pols.hashPDigest[i] = rom.program[i].hashPDigest ? 1n : 0n;
pols.bin[i] = rom.program[i].bin ? 1n : 0n;
pols.binOpcode[i] = rom.program[i].binOpcode ? BigInt(rom.program[i].binOpcode) : 0n;
pols.assert[i] = rom.program[i].assert ? 1n : 0n;
pols.line[i] = BigInt(i);
}
for (let i= rom.program.length; i<N; i++) {
pols.CONST0[i] = F.zero;
pols.CONST1[i] = F.zero;
pols.CONST2[i] = F.zero;
pols.CONST3[i] = F.zero;
pols.CONST4[i] = F.zero;
pols.CONST5[i] = F.zero;
pols.CONST6[i] = F.zero;
pols.CONST7[i] = F.zero;
pols.offset[i] = F.zero;
pols.inA[i] = F.zero;
pols.inB[i] = F.zero;
pols.inC[i] = F.zero;
pols.inD[i] = F.zero;
pols.inE[i] = F.zero;
pols.inSR[i] = F.zero;
pols.inCTX[i] = F.zero;
pols.inSP[i] = F.zero;
pols.inPC[i] = F.zero;
pols.inMAXMEM[i] = F.zero;
pols.inSTEP[i] = F.zero;
pols.inFREE[i] = F.zero;
pols.inGAS[i] = F.zero;
pols.inRR[i] = F.zero;
pols.inHASHPOS[i] = F.zero;
pols.inROTL_C[i] = F.zero;
pols.setA[i] = F.zero;
pols.setB[i] = F.zero;
pols.setC[i] = F.zero;
pols.setD[i] = F.zero;
pols.setE[i] = F.zero;
pols.setSR[i] = F.zero;
pols.setCTX[i] = F.zero;
pols.setSP[i] = F.zero;
pols.setPC[i] = F.zero;
pols.setGAS[i] = F.zero;
pols.setMAXMEM[i] = F.zero;
pols.setRR[i] = F.zero;
pols.setHASHPOS[i] = F.zero;
pols.JMP[i] = F.zero;
pols.JMPC[i] = F.zero;
pols.JMPN[i] = F.zero;
pols.incStack[i] = F.zero;
pols.incCode[i] = F.zero;
pols.isStack[i] = F.zero;
pols.isCode[i] = F.zero;
pols.isMem[i] = F.zero;
pols.ind[i] = F.zero;
pols.indRR[i] = F.zero;
pols.useCTX[i] = F.zero;
pols.mOp[i] = F.zero;
pols.mWR[i] = F.zero;
pols.sRD[i] = F.zero;
pols.sWR[i] = F.zero;
pols.arith[i] = F.zero;
pols.arithEq0[i] = F.zero;
pols.arithEq1[i] = F.zero;
pols.arithEq2[i] = F.zero;
pols.arithEq3[i] = F.zero;
pols.memAlign[i] = F.zero;
pols.memAlignWR[i] = F.zero;
pols.memAlignWR8[i] = F.zero;
pols.hashK[i] = F.zero;
pols.hashKLen[i] = F.zero;
pols.hashKDigest[i] = F.zero;
pols.hashP[i] = F.zero;
pols.hashPLen[i] = F.zero;
pols.hashPDigest[i] = F.zero;
pols.bin[i] = F.zero;
pols.binOpcode[i] = F.zero;
pols.assert[i] = F.zero;
pols.line[i] = BigInt(i);
}
}
以zkevm-proverjs/test/zkasm/counters/arith.zkasm为例:
start:
STEP => A
0 :ASSERT
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 => A,B,C,D :ARITH
CNT_ARITH => A
1 :ASSERT
CNT_ARITH => A
1 :ASSERT
0x2000000000000000000000000000000000000000000000000000000000000001n => A
0x100 => B
0x73 => C
0x20 => D
0x173 :ARITH
2 => A
CNT_ARITH :ASSERT
0 => A
CNT_KECCAK_F: ASSERT
CNT_MEM_ALIGN :ASSERT
CNT_POSEIDON_G :ASSERT
CNT_PADDING_PG :ASSERT
end:
0 => A,B,C,D,E,CTX, SP, PC, GAS, MAXMEM, SR
finalWait:
${beforeLast()} : JMPN(finalWait)
: JMP(start)
opINVALID:
经const rom = await zkasm.compile(path.join(__dirname, "zkasm", zkasmFile));
zkasmcom 编译后的结果为:
{
"program": [
{
"inSTEP": "1",
"setA": 1,
"line": 3,
"fileName": "arith.zkasm",
"lineStr": " STEP => A"
},
{
"CONST": "0",
"assert": 1,
"line": 4,
"fileName": "arith.zkasm",
"lineStr": " 0 :ASSERT"
},
{
"CONST": "0",
"setA": 1,
"line": 6,
"fileName": "arith.zkasm",
"lineStr": " 0 => A"
},
{
"inCntArith": "1",
"assert": 1,
"line": 7,
"fileName": "arith.zkasm",
"lineStr": " CNT_ARITH :ASSERT"
},
{
"inCntBinary": "1",
"assert": 1,
"line": 8,
"fileName": "arith.zkasm",
"lineStr": " CNT_BINARY :ASSERT"
},
{
"inCntKeccakF": "1",
"assert": 1,
"line": 9,
"fileName": "arith.zkasm",
"lineStr": " CNT_KECCAK_F: ASSERT"
},
{
"inCntMemAlign": "1",
"assert": 1,
"line": 10,
"fileName": "arith.zkasm",
"lineStr": " CNT_MEM_ALIGN :ASSERT"
},
{
"inCntPoseidonG": "1",
"assert": 1,
"line": 11,
"fileName": "arith.zkasm",
"lineStr": " CNT_POSEIDON_G :ASSERT"
},
{
"inCntPaddingPG": "1",
"assert": 1,
"line": 12,
"fileName": "arith.zkasm",
"lineStr": " CNT_PADDING_PG :ASSERT"
},
{
"CONST": "0",
"setA": 1,
"setB": 1,
"setC": 1,
"setD": 1,
"arith": 1,
"arithEq0": 1,
"line": 14,
"fileName": "arith.zkasm",
"lineStr": " 0 => A,B,C,D :ARITH"
},
{
"inCntArith": "1",
"setA": 1,
"line": 16,
"fileName": "arith.zkasm",
"lineStr": " CNT_ARITH => A"
},
{
"CONST": "1",
"assert": 1,
"line": 17,
"fileName": "arith.zkasm",
"lineStr": " 1 :ASSERT"
},
{
"inCntArith": "1",
"setA": 1,
"line": 19,
"fileName": "arith.zkasm",
"lineStr": " CNT_ARITH => A"
},
{
"CONST": "1",
"assert": 1,
"line": 20,
"fileName": "arith.zkasm",
"lineStr": " 1 :ASSERT"
},
{
# CONSTL为0x2000000000000000000000000000000000000000000000000000000000000001n,以8个寄存器CONST0~CONST7表示,对应CONST7值为0x20000000=536870912,CONST0=1。
"CONSTL": "14474011154664524427946373126085988481658748083205070504932198000989141204993",
"setA": 1,
"line": 22,
"fileName": "arith.zkasm",
"lineStr": " 0x2000000000000000000000000000000000000000000000000000000000000001n => A"
},
{
"CONST": "256",
"setB": 1,
"line": 23,
"fileName": "arith.zkasm",
"lineStr": " 0x100 => B"
},
{
"CONST": "115",
"setC": 1,
"line": 24,
"fileName": "arith.zkasm",
"lineStr": " 0x73 => C"
},
{
"CONST": "32",
"setD": 1,
"line": 25,
"fileName": "arith.zkasm",
"lineStr": " 0x20 => D"
},
{
"CONST": "371",
"arith": 1,
"arithEq0": 1,
"line": 26,
"fileName": "arith.zkasm",
"lineStr": " 0x173 :ARITH"
},
{
"CONST": "2",
"setA": 1,
"line": 29,
"fileName": "arith.zkasm",
"lineStr": " 2 => A"
},
{
"inCntArith": "1",
"assert": 1,
"line": 30,
"fileName": "arith.zkasm",
"lineStr": " CNT_ARITH :ASSERT"
},
{
"CONST": "0",
"setA": 1,
"line": 32,
"fileName": "arith.zkasm",
"lineStr": " 0 => A"
},
{
"inCntKeccakF": "1",
"assert": 1,
"line": 33,
"fileName": "arith.zkasm",
"lineStr": " CNT_KECCAK_F: ASSERT"
},
{
"inCntMemAlign": "1",
"assert": 1,
"line": 34,
"fileName": "arith.zkasm",
"lineStr": " CNT_MEM_ALIGN :ASSERT"
},
{
"inCntPoseidonG": "1",
"assert": 1,
"line": 35,
"fileName": "arith.zkasm",
"lineStr": " CNT_POSEIDON_G :ASSERT"
},
{
"inCntPaddingPG": "1",
"assert": 1,
"line": 36,
"fileName": "arith.zkasm",
"lineStr": " CNT_PADDING_PG :ASSERT"
},
{
"CONST": "0",
"setA": 1,
"setB": 1,
"setC": 1,
"setD": 1,
"setE": 1,
"setCTX": 1,
"setSP": 1,
"setPC": 1,
"setGAS": 1,
"setMAXMEM": 1,
"setSR": 1,
"line": 39,
"fileName": "arith.zkasm",
"lineStr": " 0 => A,B,C,D,E,CTX, SP, PC, GAS, MAXMEM, SR"
},
{
"freeInTag": {
"op": "functionCall",
"funcName": "beforeLast",
"params": []
},
"inFREE": "1",
"JMPC": 0,
"JMPN": 1,
"offset": 27,
"line": 42,
"offsetLabel": "finalWait",
"fileName": "arith.zkasm",
"lineStr": " ${beforeLast()} : JMPN(finalWait)"
},
{
"JMP": 1,
"JMPC": 0,
"JMPN": 0,
"offset": 0,
"line": 44,
"offsetLabel": "start",
"fileName": "arith.zkasm",
"lineStr": " : JMP(start)"
}
],
"labels": {
"start": 0,
"end": 26,
"finalWait": 27,
"opINVALID": 29
}
}
对应的各常量多项式的赋值为:
index | CONST0 | CONST1 | CONST2 | CONST3 | CONST4 | CONST5 | CONST6 | CONST7 | offset | incStack | incCode | isStack | isCode | isMem | ind | indPR | useCTX | mOp | mWR | sWR | sRD | arith | arithEq0 | arithEq1 | arithEq2 | arithEq3 | memAlign | memAlignWR | memAlignWR8 | hashK | hashKLen | hashDigest | hashP | hashPLen | hashPDigest | bin | binOpcode | assert | line | inA | inB | inC | inROTL_C | inD | inE | inSR | inFREE | inCTX | inSP | inPC | inGAS | inMAXMEM | inHASHPOS | inSTEP | inPR | setA | setB | setC | setD | setE | setSR | setCTX | setSP | setPC | setGAS | setMAXMEM | setHASHPOS | JMP | JMPN | JMPC | setPR |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
2 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 2 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
3 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 3 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
4 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 4 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
5 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 5 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
6 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 6 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
7 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 7 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
8 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 8 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
9 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 9 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 1 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
10 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 10 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
11 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 11 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
12 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 12 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
13 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 13 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
14 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 536870912 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 14 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
15 | 256 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 15 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
16 | 115 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 16 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
17 | 32 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 17 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
18 | 371 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 18 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
19 | 2 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 19 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
20 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 20 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
21 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 21 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
22 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 22 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
23 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 23 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
24 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 24 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
25 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 25 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
26 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 26 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 0 | 0 | 0 |
27 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 27 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 27 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 |
28 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 28 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 |
29 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 29 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
⋮ \vdots ⋮ | ⋮ \vdots ⋮ | ⋮ \vdots ⋮ | ⋮ \vdots ⋮ | ⋮ \vdots ⋮ | ⋮ \vdots ⋮ | ⋮ \vdots ⋮ | ⋮ \vdots ⋮ | ⋮ \vdots ⋮ | ⋮ \vdots ⋮ | ⋮ \vdots ⋮ | ⋮ \vdots ⋮ | ⋮ \vdots ⋮ | ⋮ \vdots ⋮ | ⋮ \vdots ⋮ | ⋮ \vdots ⋮ | ⋮ \vdots ⋮ | ⋮ \vdots ⋮ | ⋮ \vdots ⋮ | ⋮ \vdots ⋮ | ⋮ \vdots ⋮ | ⋮ \vdots ⋮ | ⋮ \vdots ⋮ | ⋮ \vdots ⋮ | ⋮ \vdots ⋮ | ⋮ \vdots ⋮ | ⋮ \vdots ⋮ | ⋮ \vdots ⋮ | ⋮ \vdots ⋮ | ⋮ \vdots ⋮ | ⋮ \vdots ⋮ | ⋮ \vdots ⋮ | ⋮ \vdots ⋮ | ⋮ \vdots ⋮ | ⋮ \vdots ⋮ | ⋮ \vdots ⋮ | ⋮ \vdots ⋮ | ⋮ \vdots ⋮ | ⋮ \vdots ⋮ | ⋮ \vdots ⋮ | ⋮ \vdots ⋮ | ⋮ \vdots ⋮ | ⋮ \vdots ⋮ | ⋮ \vdots ⋮ | ⋮ \vdots ⋮ | ⋮ \vdots ⋮ | ⋮ \vdots ⋮ | ⋮ \vdots ⋮ | ⋮ \vdots ⋮ | ⋮ \vdots ⋮ | ⋮ \vdots ⋮ | ⋮ \vdots ⋮ | ⋮ \vdots ⋮ | ⋮ \vdots ⋮ | ⋮ \vdots ⋮ | ⋮ \vdots ⋮ | ⋮ \vdots ⋮ | ⋮ \vdots ⋮ | ⋮ \vdots ⋮ | ⋮ \vdots ⋮ | ⋮ \vdots ⋮ | ⋮ \vdots ⋮ | ⋮ \vdots ⋮ | ⋮ \vdots ⋮ | ⋮ \vdots ⋮ | ⋮ \vdots ⋮ | ⋮ \vdots ⋮ | ⋮ \vdots ⋮ | ⋮ \vdots ⋮ | ⋮ \vdots ⋮ | ⋮ \vdots ⋮ | ⋮ \vdots ⋮ |
2 21 − 1 2^{21}-1 221−1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 2 21 − 1 2^{21}-1 221−1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
byte4.pil主要用于构建任意32-bit(4字节)数字,其具有常量多项式SET——奇数行为1,偶数行为0。
/*
This state machine is able to builds any number of 4 bytes (32 bits)
Example for building numbers: 0x00030007, 0x12345678, 0x00050009 and 0
SET freeIN out out'
w^0 1 3 0 3
w^1 0 7 3 0x00030007
w^2 1 0x1234 0x00030007 0x1234
w^3 0 0x5678 0x1234 0x12345678
w^4 1 5 0x12345678 5
w^5 0 9 5 0x50009
w^6 1 0 0x50009 0
w^7 0 0 0 0
*/
include "global.pil";
namespace Byte4(%N);
/// Constant Polynomials
pol constant SET; // 1, 0, 1, 0, 1, 0 ......
/// State Polynomials
pol commit freeIN;
pol commit out;
freeIN in Global.BYTE2; // 0, 1, 2, , 65535
out' = SET*freeIN +
(1-SET)*(out * 2**16 + freeIN);
padding_kk.pil中的常量多项式有:
/* Read Data output
crLatch * crValid {addr, crOffset - crLen -1, crLen, crV0C, crV1C, crV2C, crV3C, crV4C, crV5C, crV6C, crV7C}
*/
/* Read Len output
lastHashLatch {addr, len}
*/
/* Read Len digest
lastHashLatch { addr, hash0, hash1, hash2, hash3, hash4, hash5, hash6, hash7 }
*/
namespace PaddingKK(%N);
// Polynomials that are used to compute a hash chunk
pol constant r8Id;
pol constant lastBlock;
pol constant lastBlockLatch;
pol constant r8valid;
pol constant sOutId;
pol constant forceLastHash;
pol constant k_crOffset, k_crF0, k_crF1, k_crF2, k_crF3, k_crF4, k_crF5, k_crF6, k_crF7;
pol constant crValid;
具体的赋值逻辑为:
const BYTESPERBLOCK = 136;
const BlockSize = 158418;
module.exports.buildConstants = async function (pols) {
const poseidon = await buildPoseidon();
const F = poseidon.F;
const N = pols.lastBlock.length;
const nBlocks = 9*Math.floor((N-1)/BlockSize);
let p =0;
pols.k_crF = [];
for (let i=0; i<8; i++) {
pols.k_crF[i] = pols[`k_crF${i}`];
}
for (let i=0; i<nBlocks; i++) {
const bytesBlock = 136;
for (let j=0; j<bytesBlock; j++) {
pols.lastBlock[p] = (j == bytesBlock-1) ? 1n : 0n;
pols.lastBlockLatch[p] = (j == bytesBlock-1) ? 1n : 0n;
pols.crValid[p] = F.one;
pols.r8Id[p] = F.e(p);
pols.sOutId[p] = (j == bytesBlock-1) ? F.e(i) : F.zero;
pols.forceLastHash[p] = ((j == bytesBlock-1)&&(i==nBlocks-1)) ? F.one : F.zero;
pols.r8valid[p] = F.one;
p += 1;
}
}
for (let i=p; i<N; i++) {
pols.crValid[i] = F.zero;
pols.r8Id[i] = F.zero; // Must repeat the first byte
pols.lastBlock[i] = i<N-1 ? F.zero : F.one;
pols.lastBlockLatch[i] = F.zero;
pols.sOutId[i] = F.zero;
pols.forceLastHash[i] = i==N-1 ? F.one : F.zero;
pols.r8valid[i] = F.zero;
}
for (let i=0; i<32; i++) {
pols.k_crOffset[i] = BigInt(i);
const acci = Math.floor(i / 4);
const sh = BigInt((i % 4)*8);
for (let k=0; k<8; k++) {
pols.k_crF[k][i] = (k == acci) ? BigInt(1n << sh) : 0n;
}
}
for (let i=32; i<N; i++) {
pols.k_crOffset[i] = pols.k_crOffset[0];
for (let k=0; k<8; k++) {
pols.k_crF[k][i] = pols.k_crF[k][0]
}
}
}
arith.pil中的常量多项式有:
namespace Arith(%N);
pol constant BYTE2_BIT19;
pol constant SEL_BYTE2_BIT19;
pol constant GL_SIGNED_4BITS_C0;
pol constant GL_SIGNED_4BITS_C1;
pol constant GL_SIGNED_4BITS_C2;
pol constant GL_SIGNED_18BITS;
pol constant CLK[32]; // 1 if CLK==0 and 0 if CLK!=0
相应的赋值逻辑为:
module.exports.buildConstants = async function (pols) {
const N = pols.CLK[0].length;
buildClocks(pols, N, 32);
buildByte2Bits16(pols, N);
buildRange(pols, N, 'GL_SIGNED_4BITS_C0', -16n, 16n);
buildRange(pols, N, 'GL_SIGNED_4BITS_C1', -16n, 16n, 33);
buildRange(pols, N, 'GL_SIGNED_4BITS_C2', -16n, 16n, 33*33);
buildRange(pols, N, 'GL_SIGNED_18BITS', -(2n**18n), (2n**18n));
}
function buildByte2Bits16(pols, N) {
const modB1 = (2 ** 16);
const modB2 = (2 ** 19);
const modBase = modB1 + modB2
for (let i = 0; i < N; i++) {
const value = i % modBase;
pols.SEL_BYTE2_BIT19[i] = (i < modB1 ? 0n:1n);
pols.BYTE2_BIT19[i] = BigInt(value);
}
}
function buildClocks(pols, N, clocksByCycle) {
for (let i = 0; i < clocksByCycle; i++) {
for (let j = 0; j < N; ++j) {
pols.CLK[i][j] = ((j + (clocksByCycle - i)) % clocksByCycle) == 0 ? 1n : 0n;
}
}
}
function buildRange(pols, N, name, fromValue, toValue, steps = 1) {
let value = fromValue;
let csteps = steps;
for (let i = 0; i < N; i++) {
pols[name][i] = value;
csteps -= 1;
if (csteps <= 0) {
csteps = steps;
if (value === toValue) value = fromValue;
else value += 1n;
}
}
}
其中CLK[0]~CLK[31]常量多项式的赋值为:【对角线值为1,以32行为一个周期,循环重复】
index | CLK[0] | CLK[1] | CLK[2] | ⋯ \cdots ⋯ | CLK[31] |
---|---|---|---|---|---|
0 | 1 | 0 | 0 | ⋯ \cdots ⋯ | 0 |
1 | 0 | 1 | 0 | ⋯ \cdots ⋯ | 0 |
2 | 0 | 0 | 1 | ⋯ \cdots ⋯ | 0 |
⋮ \vdots ⋮ | ⋮ \vdots ⋮ | ⋮ \vdots ⋮ | ⋮ \vdots ⋮ | ⋮ \vdots ⋮ | ⋮ \vdots ⋮ |
31 | 0 | 0 | 0 | ⋯ \cdots ⋯ | 1 |
32 | 1 | 0 | 0 | ⋯ \cdots ⋯ | 0 |
33 | 0 | 1 | 0 | ⋯ \cdots ⋯ | 0 |
34 | 0 | 0 | 1 | ⋯ \cdots ⋯ | 0 |
⋮ \vdots ⋮ | ⋮ \vdots ⋮ | ⋮ \vdots ⋮ | ⋮ \vdots ⋮ | ⋮ \vdots ⋮ | ⋮ \vdots ⋮ |
63 | 0 | 0 | 0 | ⋯ \cdots ⋯ | 1 |
⋮ \vdots ⋮ | ⋮ \vdots ⋮ | ⋮ \vdots ⋮ | ⋮ \vdots ⋮ | ⋮ \vdots ⋮ | ⋮ \vdots ⋮ |
SEL_BYTE2_BIT19常量多项式的取值为:
BYTE2_BIT19常量多项式的取值为:
GL_SIGNED_4BITS_C0常量多项式的取值为:buildRange(pols, N, 'GL_SIGNED_4BITS_C0', -16n, 16n);
GL_SIGNED_4BITS_C1常量多项式的取值为:buildRange(pols, N, 'GL_SIGNED_4BITS_C1', -16n, 16n, 33);
GL_SIGNED_4BITS_C2常量多项式的取值为:buildRange(pols, N, 'GL_SIGNED_4BITS_C2', -16n, 16n, 33*33);
GL_SIGNED_18BITS常量多项式的取值为:buildRange(pols, N, 'GL_SIGNED_18BITS', -(2n**18n), (2n**18n));
binary.pil中的常量多项式有:
// ##############################################################
// CONSTANT POLINOMIALS
// ##############################################################
// Plockup polinomials
// ==============================================================
// ==== IN ====
// P_OPCODE (3 bits) Operation code
// P_CIN (1 bits) Carry in
// P_LAST (1 bits) Last byte
// P_A (8 bits) Input A
// P_B (8 bits) Input B
// ==== OUT ======
// P_C (8 bits) Output C
// P_COUT (1 bits) Carry out
// P_USE_CARRY (1 bits) Carry out
// ==== TOTAL ====
// 3 + 1 + 1 + 8 + 8 = 21 bits
// ==============================================================
// NAME | 0 | 1 | 2 | 3 | ... | 32 |
// ==============================================================
// RESET | 1 | 0 | 0 | 0 | ... | 1 |
// FACTOR0 | 0x1 | 0x100 | 0x10000 | 0x1000000 | 0x0 | 0x0 | ... | 0x0 | 0x0 | 0x0 | 0x0 |
// FACTOR1 | 0x0 | 0x0 | 0x0 | 0x0 | 0x1 | 0x100 | ... | 0x0 | 0x0 | 0x0 | 0x0 |
// ...
// FACTOR7 | 0x0 | 0x0 | 0x0 | 0x0 | 0x0 | 0x0 | ... | 0x1 | 0x100 | 0x10000 | 0x1000000 |
pol constant P_OPCODE, P_A, P_B, P_CIN, P_LAST, P_USE_CARRY;
pol constant P_C, P_COUT;
pol constant RESET;
pol constant FACTOR[8];
Polygon zkEVM的Binary状态机中的运算是基于byte运行的,每个256-bit数字需以8个32-bit(4-byte)寄存器来表示。【let REGISTERS_NUM = 8; let BYTES_PER_REGISTER = 4;
】
每32 cycle结束时,通过RESET
寄存器来重置寄存器值,并使用FACTOR
寄存器来进行正确更新,如:a0' = a0 * (1 - RESET) + freeInA * FACTOR[0];
。
FACTOR[0]-FACTOR[7]常量多项式赋值为:
/* =========
FACTORS
=========
FACTOR0 => 0x1 0x100 0x10000 0x01000000 0x0 0x0 0x0 0x0 ... 0x0 0x0 0x0 0x0 0x1 0x100 0x10000 0x01000000 0x0 ...
FACTOR1 => 0x0 0x0 0x0 0x0 0x1 0x100 0x10000 0x01000000 ... 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 ...
...
FACTOR7 => 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 ... 0x1 0x100 0x10000 0x01000000 0x0 0x0 0x0 0x0 0x0 ...
*/
RESET常量多项式的赋值为:【第0、255、511……n*256-1 位置处的值为1,其它位置均为0】
/* =========
RESET
=========
1 0 0 ... { REGISTERS_NUM * BYTES_PER_REGISTER } ... 0 1 0 ... { REGISTERS_NUM * BYTES_PER_REGISTER } 0
1 0 0 ... { REGISTERS_NUM * BYTES_PER_REGISTER } ... 0 1 0 ... { REGISTERS_NUM * BYTES_PER_REGISTER } 0
...
1 0 0 ... { REGISTERS_NUM * BYTES_PER_REGISTER } ... 0 1 0 ... { REGISTERS_NUM * BYTES_PER_REGISTER } 0
*/
P_A常量多项式赋值为:【 2 8 ∗ 2 8 2^8*2^8 28∗28个0, 2 8 ∗ 2 8 2^8*2^8 28∗28个1,……, 2 8 ∗ 2 8 2^8*2^8 28∗28个15;然后一共重复该过程 N / ( 2 8 ∗ 2 8 ) N/(2^8*2^8) N/(28∗28)次。】
/* ============
A
=========
0 .. {size} .. 0 1 .. {size} .. 1 ... {size} ... 15 ... {size} ... 15 (size * size)
0 .. {size} .. 0 1 .. {size} .. 1 ... {size} ... 15 ... {size} ... 15
...
0 .. {size} .. 0 1 .. {size} .. 1 ... {size} ... 15 ... {size} ... 15
*/
P_B常量多项式赋值为:【0-15,重复 2 8 2^8 28次;再重复 N / ( 2 8 ∗ 2 8 ) N/(2^8*2^8) N/(28∗28)次。】
/* =========
B
=========
0 1 2 .. {size} .. 15 0 1 2 .. {size} .. 15 0 1 2 .. {size} .. 15 0 1 2 ... {size} ... 15 (size * size)
0 1 2 .. {size} .. 15 0 1 2 .. {size} .. 15 0 1 2 .. {size} .. 15 0 1 2 ... {size} ... 15 (size * size)
...
0 1 2 .. {size} .. 15 0 1 2 .. {size} .. 15 0 1 2 .. {size} .. 15 0 1 2 ... {size} ... 15 (size * size)
*/
P_CIN常量多项式赋值为:【 2 8 ∗ 2 8 2^8*2^8 28∗28个0, 2 8 ∗ 2 8 2^8*2^8 28∗28个1;重复该过程 N / ( 2 ∗ 2 8 ∗ 2 8 ) N/(2*2^8*2^8) N/(2∗28∗28)次。】
/*
=========
CIN
=========
0 0 0 ... {AccumulatedSize} ... 0 0 0 1 1 1 ... {AccumulatedSize} ... 1 1 1
0 0 0 ... {AccumulatedSize} ... 0 0 0 1 1 1 ... {AccumulatedSize} ... 1 1 1
...
0 0 0 ... {AccumulatedSize} ... 0 0 0 1 1 1 ... {AccumulatedSize} ... 1 1 1
*/
P_OPCODE常量多项式赋值为:【其中current_size为 2 8 ∗ 2 8 ∗ 2 1 ∗ 2 1 2^8*2^8*2^1*2^1 28∗28∗21∗21】
/*
=========
OPCODE
=========
0 0 0 ... {current_size} ... 0 0 0
1 1 1 ... {current_size} ... 1 1 1
2 2 2 ... {current_size} ... 2 2 2
...
*/
P_LAST常量多项式赋值为:【accumulated_size个0,accumulated_size个1;重复该过程N/(accumulated_size*2)次。其中accumulated_size为 2 8 ∗ 2 8 ∗ 2 1 2^8*2^8*2^1 28∗28∗21。】
P_C、P_COUT、P_USE_CARRY常量多项式赋值为:【其本质是为所支持的所有运算构建相应的plookup table。有约束:{last, opcode, freeInA, freeInB , cIn, useCarry ,freeInC, cOut} in {P_LAST, P_OPCODE, P_A, P_B, P_CIN, P_USE_CARRY, P_C, P_COUT};
】
buildP_C_P_COUT_P_USE_CARRY(
pols.P_A,
pols.P_B,
pols.P_CIN,
pols.P_LAST,
pols.P_OPCODE,
pols.P_USE_CARRY,
pols.P_C,
pols.P_COUT,
N);
/*
=========
C & COUT
=========
1 => ADD
* Extract less signative byte -> C
* Get the carry out -> COUT
0 => AND
* A & B -> C
* 0 -> COUT (AND doesn't have carry)
。。。。。。
default
* 0 -> C
* 0 -> COUT
*/
mem.pil中的常量多项式有:
pol constant INCS; // 1......N
pol constant ISNOTLAST; // 1, 1, 1, .........1, 1, 0
具体的赋值为:
INCS = ( 1 , 2 , 3 , … , N − 1 , N ⏟ N ) \texttt{INCS} = (\underbrace{1, 2, 3, \dots,N-1, N}_{N}) INCS=(N 1,2,3,…,N−1,N)
ISNOTLAST = ( 1 , 1 , 1 , … , 1 , 0 ⏟ N ) \texttt{ISNOTLAST} = (\underbrace{1, 1, 1, \dots,1, 0}_{N}) ISNOTLAST=(N 1,1,1,…,1,0)
mem_align.pil中的常量多项式有:
// BYTE2A = 0 (x256), 1 (x256), 2 (x256), ..., 255 (x256)
pol constant BYTE2A;
// BYTE2B = 0, 1, 2, 4, **, 255, 0, 1, ..., 255
pol constant BYTE2B;
pol constant BYTE_C3072;
// FACTOR was same for all combinations of offset, wr8, wr256 is a f(step)
// FACTOR[7] = 2**24, 2**16, 2**8, 1, 0 (x60)
// FACTOR[6] = 0, 0, 0, 0, 2**24, 2**16, 2**8, 1, 0 (x56)
// FACTOR[5] = 0, 0, 0, 0, 0, 0, 0, 0, 2**24, 2**16, 2**8, 1, 0 (x52)
// :
// FACTOR[0] = 0 (x28), 2**24, 2**16, 2**8, 1, 0 (x32)
pol constant FACTOR[8];
// FACTOR change according the combinations of offset, wr8, wr256 and step.
pol constant FACTORV[8];
// STEP = 0,1,2,...,62,63,0,1,2,...
pol constant STEP;
// STEP
// 0 - 1023 WR256 = 0 WR8 = 0
// 1024 - 2047 WR256 = 1 WR8 = 0
// 2048 - 3071 WR256 = 0 WR8 = 1
pol constant WR256;
pol constant WR8;
// OFFSET = 0 (x64), 1 (x64), ... , 31 (x64), 32 (x64), 0 (x64), 1 (x64), ...
pol constant OFFSET; // 0 - 31
// RESET = 1, 0 (x63), 1, 0 (x63)
pol constant RESET;
pol constant SELM1;