本文提出了改进 FOCIL 隐私性的一种新方法,该方法基于可链接环签名(LRS),允许验证者私下发布包含列表,从而隐藏包含者的身份。该方案包括一个私有抽奖协议,从验证者集中选择包含者委员会,以及一个匿名化包含者消息的 LRS 方案,并提出了一个基于通用 SNARK 的 LRS 实例化方案。目标是激发对更高效、更优雅的LRS方案的专业构建的研究。
_作者:George, Benedikt 和 Thomas。_
感谢 Francesco 的讨论和评论。
我们提出了一种改进 FOCIL (EIP-7805) 隐私的替代方法。受到 匿名包含列表 工作的启发,并专注于 includer 隐私,我们提出了一个简单的协议,基于可链接环签名 (LRS),允许验证者私下发布包含列表。我们还提出了一个基于通用 SNARK 的 LRS 方案。
我们撰写本文档的目标是激发对专门构造的研究,与我们的 SNARK 构造相比,这些构造可以更高效、更优雅地实例化这个 LRS 基本组件。
在 FOCIL 中,信标链使用 RANDAO 选择一个 includer 委员会,然后由他们发布包含列表。
在这里,我们的目标是分两步隐藏这些 includer 的身份:
我们展示了如何使用 LRS 方案实现这些步骤,并提出了一个基于 SNARK 的实例化。
从抽象意义上讲,可链接环签名 (LRS) 允许签名者证明其属于某个群组,而无需透露哪个成员进行了签名,同时还可以检测到对同一密钥的重复使用。每个签名都包含一个“密钥镜像”,该镜像从私钥派生而来,但不泄露签名者的身份。如果再次使用相同的私钥,则生成的密钥镜像相同,从而允许验证者链接来自同一(匿名)签名者的多个签名,而无需暴露他们的身份。
可链接环签名是经过充分研究的密码学基本组件(例如,参见此构造)。对于本提案,我们假设以下最小 API:
生成密钥对。
在给定的公钥 环 (Ring) 上对 消息 (message) 生成环签名,并返回签名及其关联的 密钥镜像 (KeyImage)。
验证签名是否由 环 (Ring) 中的某个私钥有效生成。
这与标准可链接环签名接口相呼应,但我们直接公开密钥镜像,而不是提供单独的 Link()
函数。展望未来,使密钥镜像显式化使我们能够在私有抽奖中使用它。然后,验证者可以通过简单地比较密钥镜像来检测来自同一私钥的多个签名。我们还假设,对于未持有相应签名密钥的任何人来说,密钥镜像与随机字符串无法区分。
在每个插槽,Alice 计算她的临时环签名密钥(即,密钥镜像)并对照谓词检查它,以查看她是否赢得了抽奖。由于密钥镜像与验证者的身份公钥相关联,因此每个验证者的密钥镜像都是唯一的,因此 Alice 无法通过研磨彩票来偏袒选举。此外,由于密钥镜像对于除 Alice 之外的所有人来说看起来都是随机的,因此只有 Alice 自己会知道她赢得了抽奖,直到她决定透露自己的身份。
如果 Alice 赢得了抽奖,她就是该插槽的 includer,她应该构建和广播包含列表,并使用她的 LRS 签名密钥进行签名。
我们现在提供一个“私有 Includer 证明”协议的协议规范,使用上述 LRS 方案的 API:
每个验证者生成一个可链接环签名密钥对,并将其公钥注册到区块链:
Sk, Pk := KeyGen()
这只需要做一次,但目前信标链中没有这样的密钥注册通道。有一些方法(例如我们下面描述的基于 SNARK 的方法)可以使用验证者 BLS12-381 签名密钥用于此方案,但代价是将验证者私钥暴露给这个新的基本组件。
根据 is_includer()
的返回值选择验证者作为 includer。
def is_includer(state: BeaconState, slot: Slot, Sk: RingSigningKey, Ring) -> bool
domain = get_domain(state, DOMAIN_IL, compute_epoch_at_slot(block.slot))
signing_root = compute_signing_root(slot, domain)
_, KeyImage = Sign(Ring, Sk, signing_root)
return is_includer_impl(state, KeyImage)
def is_includer_impl(state: BeaconState, KeyImage)
modulo = max(1, len(state.validators) // TARGET_N_INCLUDERS)
return bytes_to_uint64(hash(KeyImage)[0:8]) % modulo == 0
这种方法满足了 FOCIL IL 委员会选择文档 中的保密性要求,因为只有 Alice 才能计算出自己的密钥镜像。
请注意,所有验证者赢得抽奖的概率相同,并且不按 stake 加权。
def get_inclusion_list_signature(Sk: RingSigningKey, Ring) -> RingSignature:
inclusion_list_body = compute_inclusion_list()
Signature, _ = Sign(Ring, Sk, inclusion_list_body)
return Signature
当 Alice (提议者) 从 P2P 网络接收到 IL 时,她会检查每个 IL 的以下内容:
def verify_inclusion_lists(state: BeaconState, signed_inclusion_lists: SignedInclusionList):
key_images = []
for signed_inclusion_list in signed_inclusion_list:
assert Verify(Ring, signed_inclusion_list.body, signed_inclusion_list.signature)
assert is_includer_impl(state, signed_inclusion_list.signature.key_image)
key_images.append(signed_inclusion_list.signature.key_image)
# 检查双重签名,检查重复的密钥镜像
assert len(key_images) == len(set(key_images))
类似的规则将被引入到 P2P 网络上的节点 如 EIP 建议的那样。
上述规范可以通过文献中的各种 LRS 协议来实现。下面,我们提出了一个使用通用 SNARK 的 LRS 构造,因为现有的已发布方案对于我们的用例来说效率不够高。之后,我们为 LRS 方案提供性能要求,以便与我们的用例兼容。
在本节中,我们提供一个基于通用 zk-SNARK 的 LRS 方案的实例化:
以下基于 SNARK 的方法受到了 验证者证明帖子(另请参见 ESORICS 2024 的这篇最新论文)的启发。在这种方法中,抽奖协议是使用派生的临时 BLS 公钥实现的(类似于当前使用基于 BLS 的 VRF 选择信标链聚合器的方式)。
特别是,考虑一个具有 (Sk, Pk)
作为其 BLS 身份密钥对的验证者:
def Sign(Sk, message, validators_pks, validators_pks_commitment):
derived_sk = hash(Sk)
derived_pk = G.mul(derived_sk) # derived_pk is the key image
# Proof that `derived_pk = H(Sk) * G` and that `Sk` is a log of an element in validators_pks
proof = SNARK.prove((Sk, validators_pks), (validators_pks_commitment, derived_pk, G))
signature = BLS.Sign(derived_sk, message)
return (signature, proof), derived_pk
def Verify(message, ((signature, proof), derived_pk), validators_pks_commitment):
# Check that key image (derived_pk) is properly derived from one of the validators
assert SNARK.verify(proof, (validators_pks_commitment, derived_pk, G))
assert BLS.verify(derived_pk, signature, message)
其中,validators_pks
是所有验证者的 BLS 公钥列表,validators_pks_commitment
是对 validators_pks
的 Merkle 承诺。
SNARK.Prove(w, x)
是抽象 zk-SNARK 方案的证明函数,其中 w
表示 witness,x
表示 statement。同样,SNARK.Verify(proof, x)
使用 proof
验证 statement x
。
这种方法高效且实用,并且使用正确的 SNARK 证明系统(例如,Halo2+IPA),它不需要可信设置。
但是,指定和实现 SNARK 的复杂性相当大。这是因为 SNARK 具有多个复杂的底层部分(多项式承诺方案、证明系统、算术化),并且每个部分对于安全性和性能都至关重要。
值得注意的是,上述方法通过固有地使用验证者的 BLS 身份密钥对来避免密钥注册。通常不建议这样做:你不应该在密码系统中使用并非用于此目的的长期私钥。另一种方法是使用 验证者证明 帖子中的“方法 1”,这将向协议添加显式的密钥注册步骤。密钥注册在以太坊中特别困难,因为验证者没有注册新加密密钥的标准方法,并且因为它大大增加了 BeaconState
的大小(假设我们有 100 万个验证者)。
满足以下任何 LRS 要求的都可以在这里工作:
以下是我们的私有 FOCIL 方案应涵盖的非正式安全属性列表:
每个验证者在给定的插槽中都有相同的获胜概率,并且一个验证者赢得抽奖的概率不取决于其他验证者是否获胜。此安全属性取决于 LRS 方案,该方案为给定的公钥生成唯一的密钥镜像,并且还通过在应用谓词之前将密钥镜像馈送到随机预言机中。
除非并且直到验证者发布其密钥镜像和签名,否则任何人都无法确定验证者是否已获胜。换句话说,验证者的获胜状态在它明确揭示之前都是保密的。此安全属性取决于 LRS 方案,其中密钥镜像时伪随机的,并且该对 (key_image, signature)
是不可伪造的。因此,Bob 无法派生 Alice 的密钥镜像来检查他是否赢得了抽奖。
即使验证者确实揭示了其密钥镜像和签名,外部观察者也只能了解到一个假名(即密钥镜像),并且无法将此临时身份链接到验证者的长期公钥。
攻击者无法在不知道该验证者的私钥的情况下代表获胜的验证者创建有效的签名或密钥镜像。
匿名奖励机制:研究如何在不链接其真实身份的情况下奖励匿名 includer。
LRS 的长期匿名攻击:在减少可链接环签名的匿名性方面,已经有 很多 工作。这种攻击大致通过组合密钥镜像图并运行 DM 分解 算法来实现。我们应该调查我们的环大小是否容易受到此类攻击的影响,否则考虑使用每个 epoch 都会更改的密钥镜像。
网络匿名性:网络匿名性不在本文档的范围内,但是最终将需要一个高效的匿名广播协议。
- 原文链接: ethresear.ch/t/zkfocil-i...
- 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!