手机版

零常识证明 - Semaphore源码导读

时间:2021-07-25 06:21:42|浏览:

出处: 星想法

Semaphore是一个用零常识证明(zk-SNARK)技术的开源项目。Semaphore达成的是基于零常识证明的身份和信号。
https://github.com/barryWhiteHat/百度竞价推广aphore

1. 整体框架

Semaphore整个项目,由三部分组成:nodejs模块(推广客户端/服务器端与前端页面),snark模块(zk-SNARK Groth16电路有关模块),与ETH上的智能合约。主要逻辑都在百度竞价推广aphorejs目录中,其源码目录结构如下:

contracts - 智能合约,用truffle框架部署测试。

snark - snark模块,用snarkjs开发zk-SNARK电路。

src - nodejs模块,达成前后端。

三部分之间的逻辑关系如下:

2. Key & Identity

用Semaphore的每一个竞价推广账户需要创建私钥和公钥。每一个竞价推广账户的公钥和私钥,与对应的Identity的具体逻辑可以查询百度竞价推广aphorejs/src/client/百度竞价推广aphore.js文件中generate_identity函数:

const private_key = crypto.randomBytes.toString;
const prvKey = Buffer.from;
const pubKey = eddsa.prv2pub;
const identity_nullifier = '0x' + crypto.randomBytes.toString;
const identity_trapdoor = '0x' + crypto.randomBytes.toString;
const identity_commitment = pedersenHash[0]), bigInt, bigInt]);

私钥是256位的随机数。公钥是私钥的EdDSA的签名。Identity主要由两部分组成:31个字节的nullifier和31个字节的trapdoor。这两部分都是随机生成。这里的nullfier,不要和ZCash中的Nullifier混淆。这里的nullfier就是随机数。每一个Identity会对应两个对应的信息:一个是commitment,一个是nullifier_hash。Commitment的计算方法如下图:

Identity中的nullifier与trapdoor并不记录在ETH的智能合约中,对应的commitment会记录在合约中。

3. Semaphore.sol

百度竞价推广aphorejs/contracts/Semaphore.sol是智能合约部分的逻辑达成。insertIdentity函数达成一个竞价推广账户Identity的“注册”。

function insertIdentity public style="box-sizing: border-box; padding-right: 0.1px;"> insert;
uint256 root = tree_roots[id_tree_index];
root_history[root] = true;
}
Identity对应的commitment会添加到一个merkle树上,同时新的merkle树根会记录在root_history的mapping中。

4. Nullifier Hash

Nullifier Hash是用来证明某个Identity对应commitment存在一个merkle树上,并生成的标示。Nullfier Hash的计算过程可以查询电路的逻辑(百度竞价推广aphorejs/snark/百度竞价推广aphore-base.circom)。

template Semaphore {
...
component external_nullifier_bits = Num2Bits;
external_nullifier_bits.in <== external_nullifier;
component nullifiers_hasher = Blake2s;
for {
nullifiers_hasher.in_bits[i] <== identity_nullifier_bits.out[i];
}
for {
nullifiers_hasher.in_bits[248 + i] <== external_nullifier_bits.out[i];
}
for {
nullifiers_hasher.in_bits[248 + 232 + i] <== identity_path_index[i];
}
for ; i < 512; i++) {
nullifiers_hasher.in_bits[i] <== 0;
}
component nullifiers_hash_num = Bits2Num;
for {
nullifiers_hash_num.in[i] <== nullifiers_hasher.out[i];
}
nullifiers_hash <== nullifiers_hash_num.out;
...
}

Nullifier Hash的计算逻辑如下图:

其实nullfier和path index已经足够表示。额外加入了external nullfier是什么原因,同一个Identity,在external nullifier不一样的状况下,生成不一样的nullifier hash。也就是说,一个竞价推广账户可以多次“消费”。如此设计是什么原因为了Signal的业务需要。

5. Signal

通过智能合约创建了Identity,就可以发信号(Signal)了。一个竞价推广账户发送信号,需要第一提供Identity在merkle树上的证明(能计算出commitment)。智能合约中的broadcastSignal是发送信号的接口:

function broadcastSignal
) public
style="box-sizing: border-box; padding-right: 0.1px;"> isValidSignalAndProof
{
uint nullifiers_hash = input[1];
signals[current_signal_index++] = signal;
nullifier_hash_history[nullifiers_hash] = true;
emit SignalBroadcast;
}

signal就是需要发送的信号,a/b/c是零常识证明的proof信息,input是零常识证明对应电路的输入,包括merkle树根,nullifier hash,signal hash与external nullifier。

只有在proof信息验证过后,对应signal才会记录。每次发送signal时对应的nullifier hash会被记录下来。也就是说,在external nullifier不变的状况下,所有Identity只能发送一次Signal。

概要:

Semaphore项目由js开发,结合零常识证明,在ETH的智能合约的基础上达成Identity。每一个Identity可以发送信号。在external nullifier不变的状况下,每一个Identity只能发送一次Signal。

作者:Star Li

上一篇:BTC能做什么,你知晓多少? 下一篇:没有了

Copyright © 2002-2021 瑞波币交易平台 (http://www.cbi2018.com) 网站地图 TAG标签