📰工作原理

ZKSAFE Password 工作原理

ZKPass (ZKSAFE Password简称ZKPass) 本质上是把pwdhash(密码的哈希值)存在合约里,如果说ENS是把name绑定到地址,那么ZKPass就是把pwdhash绑定到地址

为了实现签名,需要把 用户想要干什么 这个信息,用Keccak256生成datahash,再跟签名过期时间expiration、指定的链chainId、从1开始自增的nonce,用Keccak256生成fullhash

为什么用nonce?

用来确保签名不能重复提交,避免双花

在ZK电路里,使用Poseidon算法来生成hash(gas较低的hash算法),代码如下:

pragma circom 2.0.0;

include "../../node_modules/circomlib/circuits/poseidon.circom";

template Main() {
    signal input in[3];
    signal output out[3];

    component poseidon1 = Poseidon(2);
    component poseidon2 = Poseidon(2);

    poseidon1.inputs[0] <== in[0];  //pwd
    poseidon1.inputs[1] <== in[1];  //address
    out[0] <== poseidon1.out; //pwdhash

    poseidon2.inputs[0] <== poseidon1.out;
    poseidon2.inputs[1] <== in[2]; //fullhash
    out[1] <== in[2]; //fullhash
    out[2] <== poseidon2.out; //allhash
}

component main = Main();

画成逻辑图就是下图

passwordaddress生成pwdhash,确保每个用户的pwdhash都不一样

pwdhashfullhash生成allhash,确保所有的数据都有带上

最后proof就相当于给allhashpwdhashfullhash盖了个章,证明pwdhash是由password生成的,但是不知道password是啥,也证明了allhash是由passwordfullhash生成

fullhash作为输出,在合约里可以验证是否被篡改(即签名)

听起来像绕口令?

是的,还有一个坑没说,Poseidon算法的输入是254位,但是Keccak256生成的fullhash是256位,所以需要fullhash除以8再输入到ZK电路,ZKPass合约已经自动除以8了,需要前端也除以8,这样才能在ZKPass合约校验通过

补充说明

在用户侧,ZKPass只有改密码的功能,如果只是验证密码,获取pwdhash在链下就可以验证,而链上的验证通常是配合其他合约一起,做数据签名用,比如ZKSAFE合约:ZKSAFE合约把 用户想要干什么 这些参数,在合约内生成datahash传给ZKPass合约,ZKPass验证成功后,ZKSAFE合约就知道用户的密码正确,以及 用户想要干什么 这些参数没有被篡改(即签名),ZKSAFE合约就可以做下一步(提币)操作了

最后更新于