Polygon zkEVM Merkle tree的circom约束
Posted mutourend
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Polygon zkEVM Merkle tree的circom约束相关的知识,希望对你有一定的参考价值。
1. 引言
前序博客有:
代码见:
2. Poseidon哈希circom约束
3. LinearHash circom约束
template LinearHash(nInputs, eSize)
signal input in[nInputs][eSize]; //输入in元素数为nInputs*eSize
signal output out[4];
var nHashes;
if (nInputs*eSize <= 4)
nHashes = 0;
else
nHashes = (nInputs*eSize - 1)\\8 +1;
component hash[nHashes];
if (nInputs*eSize <= 4)
var curI=0;
var curE=0;
for (var i=0; i<4; i++)
if (i<nInputs*eSize)
out[i] <== in[curI][curE];
curE = curE +1;
if (curE == eSize)
curE =0;
curI ++;
else
var curInput=0;
var curC=0;
for (var i=0; i<nHashes; i++)
hash[i] = Poseidon(4);
for (var k=0; k<8; k++)
if (curInput<nInputs)
hash[i].in[k] <== in[curInput][curC];
curC++;
if (curC == eSize)
curC =0;
curInput += 1;
else
hash[i].in[k] <== 0;
for (var k=0; k<4; k++)
if (i>0)
hash[i].capacity[k] <== hash[i-1].out[k];
else
hash[i].capacity[k] <== 0;
for (var k=0; k<4; k++)
out[k] <== hash[nHashes-1].out[k];
4. Merkle tree circom约束
template Merkle(nLevels) //nLevels表示树高度
signal input value[4]; //叶子节点数据对应4个Goldilocks元素
signal input siblings[nLevels][4]; //每个节点哈希值对应4个Goldilocks元素
signal input key[nLevels]; //key数组表示所在各层的位置
signal output root[4];
component hash[nLevels];
for (var i=0; i<nLevels; i++)
hash[i] = Poseidon(4);
for (var k=0; k<4; k++)
if (i>0)
hash[i].in[k ] <== key[i]*(siblings[i][k] - hash[i-1].out[k]) + hash[i-1].out[k];
hash[i].in[k+4] <== key[i]*(hash[i-1].out[k] - siblings[i][k] ) + siblings[i][k];
else
hash[i].in[k] <== key[i]*(siblings[i][k] - value[k] ) + value[k];
hash[i].in[k+4] <== key[i]*(value[k] - siblings[i][k] ) + siblings[i][k];
hash[i].capacity[k] <== 0;
for (var k=0; k<4; k++)
root[k] <== hash[nLevels-1].out[k];
5. MerkleHash circom约束
MerkleHash本质为:以values、siblings、key为输入,以root为输出,验证相应的Merkle证明与root是否匹配。
以 s0_merkle1[q] = MerkleHash(1, 2, 2048)=MerkleHash(eSize, elementsInLinear, nLinears)
为例:
- 1)
eSize
:表示单个数据所需的Goldilocks元素数 - 2)
elementsInLinear
:表示叶子节点对应的数据数 - 3)
nLinears
:表示Merkle树中总的节点树
template MerkleHash(eSize, elementsInLinear, nLinears)
var nBits = log2(nLinears); //2^11=2048,nBits为Merkle树高度
assert(1 << nBits == nLinears); //要求nLinears为2的某幂次运算
signal input values[elementsInLinear][eSize]; //values[2][1]
signal input siblings[nBits][4]; //Merkle证明路径,每个节点为哈希值对应4个Goldilocks元素。
signal input key[nBits]; //key数组表示所在各层的位置
signal output root[4];
//对 叶子节点下原始数据进行处理,为4个Goldilocks元素。
component linearHash = LinearHash(elementsInLinear, eSize);
for (var i=0; i<elementsInLinear; i++)
for (var e=0; e<eSize; e++)
linearHash.in[i][e] <== values[i][e];
component merkle = Merkle(nBits); //nBits为树高度
for (var i=0; i<4; i++) //LinearHash处理后的数据作为Merkle树的叶子节点源数据
merkle.value[i] <== linearHash.out[i];
for (var i=0; i<nBits; i++)
merkle.key[i] <== key[i];
for (var j=0; j<4; j++)
merkle.siblings[i][j] <== siblings[i][j];
for (var i=0; i<4; i++)
root[i] <== merkle.root[i];
6. TreeSelector
s0_lowValues[q] = TreeSelector(4, 3) ; //对应get3(proof[si+1].polQueries[i][0], groupIdx)
//signal input s1_vals[8][48]; // fri 1 tree对应查询点的叶子节点(针对Goldilocks extension 3域),48为对应叶子width,
// 即: (1 << (starkStruct.steps[s-1].nBits - starkStruct.steps[s].nBits))*3
for (var i=0; i<16; i++)
for (var e=0; e<3; e++)
s0_lowValues[q].values[i][e] <== s1_vals[q][i*3+e];//即FRI下一层的叶子节点数据内容
// 取FRI下一层的查询位置
for (var i=0; i<4; i++) //key数组表示所在各层的位置
s0_lowValues[q].key[i] <== ys[q][i + 7]; //表示的即为const groupIdx =Math.floor(ys[i] / nextNGroups);
// 对应约束F.eq(get3(proof[si+1].polQueries[i][0], groupIdx), ev)
for (var e=0; e<3; e++)
s0_lowValues[q].out[e] === verifyQueries[q].out[e];
其中verifyQueries
对应VerifyQuery模板,用于验证FRI中step0的各Merkle tree中查询位置约束关系,对应starkInfo.verifierQueryCode中计算。
以s0_lowValues[q] = TreeSelector(4, 3) ;
为例,表示:
template TreeSelector(nLevels, eSize)
var n = 1 << nLevels;
signal input values[n][eSize];
signal input key[nLevels];
signal output out[eSize];
signal im[n-1][eSize];
var levelN = n\\2;
var o = 0;
var lo = 0;
for (var i=0; i<nLevels; i++)
for (var j=0; j<levelN; j++)
for (var k=0; k<eSize; k++)
if (i==0)
im[o+j][k] <== key[i]*(values[2*j+1][k] - values[2*j][k]) + values[2*j][k];
else
im[o+j][k] <== key[i]*(im[lo + 2*j+1][k] - im[lo + 2*j][k]) + im[lo + 2*j][k];
lo = o;
o = o + levelN;
levelN = levelN\\2;
for (var k=0; k<eSize; k++)
out[k] <== im[n-2][k];
附录:Polygon Hermez 2.0 zkEVM系列博客
- ZK-Rollups工作原理
- Polygon zkEVM——Hermez 2.0简介
- Polygon zkEVM网络节点
- Polygon zkEVM 基本概念
- Polygon zkEVM Prover
- Polygon zkEVM工具——PIL和CIRCOM
- Polygon zkEVM节点代码解析
- Polygon zkEVM的pil-stark Fibonacci状态机初体验
- Polygon zkEVM的pil-stark Fibonacci状态机代码解析
- Polygon zkEVM PIL编译器——pilcom 代码解析
- Polygon zkEVM Arithmetic状态机
- Polygon zkEVM中的常量多项式
- Polygon zkEVM Binary状态机
- Polygon zkEVM Memory状态机
- Polygon zkEVM Memory Align状态机
- Polygon zkEVM zkASM编译器——zkasmcom
- Polygon zkEVM哈希状态机——Keccak-256和Poseidon
- Polygon zkEVM zkASM语法
- Polygon zkEVM可验证计算简单状态机示例
- Polygon zkEVM zkASM 与 以太坊虚拟机opcode 对应集合
- Polygon zkEVM zkROM代码解析(1)
- Polygon zkEVM zkASM中的函数集合
- Polygon zkEVM zkROM代码解析(2)
- Polygon zkEVM zkROM代码解析(3)
- Polygon zkEVM公式梳理
- Polygon zkEVM中的Merkle tree
- Polygon zkEVM中Goldilocks域元素circom约束
以上是关于Polygon zkEVM Merkle tree的circom约束的主要内容,如果未能解决你的问题,请参考以下文章
Polygon zkEVM中Goldilock域元素circom约束