news 2026/9/12 13:47:26

fhEVM KMSGeneration 合约深度解析:FHE 密钥与 CRS 公共材料的链上生成与共识流程

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
fhEVM KMSGeneration 合约深度解析:FHE 密钥与 CRS 公共材料的链上生成与共识流程

fhEVM KMSGeneration 合约深度解析:FHE 密钥与 CRS 公共材料的链上生成与共识流程

【免费下载链接】fhevmFHEVM, a full-stack framework for integrating Fully Homomorphic Encryption (FHE) with blockchain applications项目地址: https://gitcode.com/GitHub_Trending/fh/fhevm

导读

KMSGeneration是 fhEVM Gateway 协议中负责编排 KMS(Key Management Service)公共材料的核心合约,它管理两类链上生成任务:FHE 加密公钥(keygen)与用于 ZKPoK 证明的 powers-of-tau 公共参考串 CRS(crsgen)。本文以 KMSGeneration 合约文档 为主体,结合仓库中 Gateway 链只读版本与以太坊主实现的源码、接口与测试,完整讲解其职责、调用入口、请求 ID 体系、KMS 节点签名共识机制以及材料读取方式,帮助合约开发者与协议运营者理解并正确使用这一关键基础设施。

KMSGeneration 在 fhEVM 协议中的定位

KMSGeneration合约用于为 fhEVM Gateway 协议编排公开的 KMS 相关材料。在 fhEVM 的双链架构中,该合约实际存在两个实现版本,职责各有侧重:

  • Gateway 链上的只读版本(v0.5.0):位于 gateway-contracts/contracts/KMSGeneration.sol,注释明确标注为view-only实现。在 KMSGeneration 迁移至以太坊之后,该合约保留在 Gateway 链上,仅用于对历史生成的密钥与 CRS 材料进行查询,不再支持全新部署,仅提供reinitializeV5()用于将既有代理升级到只读实现。
  • 以太坊(Host 链)上的主实现(v0.3.0):位于 host-contracts/contracts/KMSGeneration.sol,承担全部状态变更逻辑(keygenprepKeygenResponsekeygenResponsecrsgenRequestcrsgenResponse以及中止流程)。

两个版本共享同一套接口定义 IKMSGeneration.sol,其中明确定义了生成流程使用的两个枚举与核心结构体:

enum ParamsType { Default, // 0 Test // 1 } enum KeyType { Server, // 0 Public // 1 } struct KeyDigest { KeyType keyType; bytes digest; }

ParamsType决定生成请求使用默认参数还是测试参数;KeyType标识密钥类型;KeyDigest则记录某一类型密钥的摘要,是 KMS 节点在响应阶段提交并参与共识的核心数据。

从 GatewayConfig 文档 可以确认该合约在协议中的上下游关系:KMS 节点负责基于KMSGeneration合约的请求生成 KMS 公共材料,而GatewayConfig合约中登记的storageUrl(KMS 公共材料存储地址)正是 coprocessor 下载 FHE 计算所需公共材料的来源。

合约的两大核心职责与访问控制

原文档指出,KMSGeneration合约被用于完成两件事:

  1. 生成 FHE 密钥(FHE keys)
  2. 生成公共参考串(CRSs)

并且强调了一个关键的安全约束:所有非 view 函数要么被限制为仅合约 owner 可调用,要么被限制为仅 KMS 节点的交易发送者(transaction sender)可调用。这一约束在主实现中体现得非常清晰:

  • 请求发起函数keygencrsgenRequestabortKeygenabortCrsgen均标注onlyACLOwner修饰符(参见 host-contracts/contracts/KMSGeneration.sol);
  • 响应提交函数prepKeygenResponsekeygenResponsecrsgenResponse则通过 EIP-712 签名校验与 KMS 上下文(context)绑定来授权,只有 KMS 节点(及其关联的交易发送者)才能提交有效响应。

也就是说,owner 负责“发起”材料生成请求,KMS 节点负责“提交”生成结果并达成共识,二者职责分离,任何普通账户都无法干预生成流程。

生成 FHE 密钥(keygen)

密钥的用途与分工

如原文档所述,FHE 密钥的生成遵循“公私分离”的设计:

  • 私钥分片(key shares)由 KMS 以多方计算(MPC)方式私下共享,用于 KMS 后续解密密文;
  • 公钥提供给 coprocessor,用于对密文执行同态运算。

每个新生成的 FHE 公钥由一个全局唯一的keyId标识,coprocessor 与 KMS 均通过该 ID 引用对应密钥材料。

两阶段请求-响应流程

从主实现源码看,keygen并非一次调用即完成,而是拆分为“预处理(prep keygen)”与“正式 keygen”两个阶段,每个阶段都要求 KMS 节点提交 EIP-712 签名达成共识:

阶段一:发起请求

function keygen(ParamsType paramsType, uint256 existingKeyId) external virtual onlyACLOwner { // 检查上一个 keygen 请求是否已完成,未完成则 revert KeygenOngoing // 生成全局唯一的 prepKeygenId 与 keyId 并配对(keygenIdPairs 双向映射) // 记录 paramsType 与上下文(contextId + epochId)到 requestExtraData emit PrepKeygenRequest(prepKeygenId, paramsType, existingKeyId, extraData); }

调用keygen(paramsType, existingKeyId)后,合约会:

  • 校验上一个 keygen 请求是否已完成(isRequestDone[previousKeyId]),保证生成流程串行、不会并发堆积;
  • 自增计数器并生成一对互相关联的 ID——prepKeygenIdkeyId,存入keygenIdPairs双向映射;
  • 固定请求时的 KMS 上下文与 epoch(PROTOCOL_CONFIG.getCurrentKmsContextAndEpoch()),并将contextId + epochId编码进extraData,用于响应阶段的签名绑定与防重放;
  • 发出PrepKeygenRequest事件,通知 KMS 节点开始预处理。

阶段二:KMS 节点响应

KMS 节点随后调用prepKeygenResponse(prepKeygenId, signature)提交其 EIP-712 签名。合约会校验签名者必须是该上下文内的合法 KMS signer、且与交易发送者匹配,随后把交易发送者地址计入该请求的共识列表。当签名数量达到阈值(getKmsGenThresholdForContext)时,标记预处理完成,并发出KeygenRequest事件进入正式 keygen 阶段。

正式阶段中,KMS 节点调用keygenResponse(keyId, keyDigests, signature)提交密钥摘要数组。合约要求:

  • keyId必须对应一个真实发起的 keygen 请求;
  • keyDigests不能为空(keygen 流程总会生成至少一个密钥);
  • 对应的预处理阶段必须已经达成共识;
  • 每个 KMS signer 只能签名一次(重复签名触发KmsAlreadySignedForKeygen)。

一旦达到共识阈值,合约写入keyDigests[keyId]、更新activeKeyId,并发出ActivateKey事件,包含共识存储 URL 列表与全部密钥摘要,coprocessor 据此下载并启用新的 FHE 公钥。

从源码结构还可以推断,keygen的第二个参数existingKeyId用于“迁移请求”(migration request):当传入非零existingKeyId时,合约会校验该密钥必须是当前活跃密钥、参数类型一致且尚未附加压缩密钥集(CompressedKeySet),用于为既有密钥补充压缩密钥材料。这一能力体现在_checkMigrationRequest_checkCompressedKeySetDigest两个内部函数中(host-contracts/contracts/KMSGeneration.sol)。

生成公共参考串(crsgen)

CRS 的作用

原文档指出,CRS(Common Reference String)是基于 powers-of-tau 的相关随机材料,由 KMS 以安全方式生成,是构造特定 ZKPoK(零知识证明)所必需的——尤其是用于证明“某个明文确实加密在某个 FHE 密钥之下”。因此 CRS 是 fhEVM 输入验证与密文证明链路的基础设施。

请求与响应

与 keygen 类似,CRS 生成也由 owner 发起、KMS 节点响应并共识:

function crsgenRequest(uint256 maxBitLength, ParamsType paramsType) external virtual onlyACLOwner { // 检查上一个 crsgen 请求是否已完成 // 自增计数器生成全局唯一 crsId $.crsMaxBitLength[crsId] = maxBitLength; $.requestParamsType[crsId] = paramsType; emit CrsgenRequest(crsId, maxBitLength, paramsType, extraData); }

与 keygen 相比,crsgen 有两个值得注意的参数差异:

  • maxBitLength:本次 CRS 生成所允许的最大比特长度,会被存储到crsMaxBitLength[crsId]中,并参与后续 EIP-712 摘要的计算,防止响应与请求参数不一致;
  • 请求不经过“预处理”阶段,crsgenRequest直接产出crsId

KMS 节点随后调用crsgenResponse(crsId, crsDigest, signature)提交 CRS 摘要(crsDigestbytes)。达到共识阈值后,合约写入crsDigests[crsId]、更新activeCrsId,发出ActivateCrs事件,同样携带共识存储 URL 列表。

中止机制

主实现还提供abortKeygen(prepKeygenId)abortCrsgen(crsId)两个仅 owner 可调用的中止函数,用于在请求发起后、共识达成前中止流程,将对应请求标记为完成以解除对后续生成的阻塞。中止过的请求其consensusDigest保持零值,读取材料时会分别触发KeyAborted/CrsAborted错误。

全局唯一的请求 ID 体系

为什么keyIdcrsId是“全局唯一”的?答案在 host-contracts/contracts/shared/Constants.sol 中的 ID 编码设计:每个请求 ID 的高位字节携带类型标签,低位 31 字节为计数器值,格式形如:

请求类型类型标签(首字节)常量ID 格式
预处理 keygen0x03PREP_KEYGEN_COUNTER_BASE[0000 0011 | counter_1..31]
keygen0x04KEY_COUNTER_BASE[0000 0100 | counter_1..31]
crsgen0x05CRS_COUNTER_BASE[0000 0101 | counter_1..31]

由于计数器从各自的 base 值(类型标签左移 248 位)起步递增,不同请求类型之间永远不会产生 ID 重叠。这也是为什么合约可以用同一个keygenIdPairs映射同时存储 prepKeygen↔keygen 的双向关联——ID 的全局唯一性保证了映射不会冲突。

共识机制:EIP-712 签名与 KMS 阈值

KMS 材料生成的安全根基是多节点签名共识。整个流程围绕以下设计展开:

  1. 签名结构(Typed Data):合约定义了PrepKeygenVerificationKeygenVerificationCrsgenVerification三种 EIP-712 类型,并显式声明嵌套结构体KeyDigest(uint8 keyType,bytes digest)的类型哈希。keyDigests数组的编码顺序必须与 KMS 节点一致(注释明确要求:第一个元素对应 Server 类型,第二个对应 Public 类型),否则摘要不匹配。
  2. 上下文固定(context pinning):每个请求在发起时固定当时的 KMS 上下文与 epoch(requestExtraData编码contextId + epochId)。响应时,签名校验针对该固定上下文进行,而不是“当前活跃上下文”——这样即使请求进行中发生了上下文轮换,也不会使在途响应失效或导致共识在不同委员会之间分裂。
  3. 签名者-交易发送者匹配_validateEIP712Signature通过ECDSA.recover恢复签名者地址,随后要求签名者必须是指定上下文内的 KMS signer,且必须与该节点的交易发送者绑定(KmsSignerDoesNotMatchTxSender错误兜底)。
  4. 阈值判定_isKmsConsensusReachedForContext读取PROTOCOL_CONFIG.getKmsGenThresholdForContext(contextId),当同意签名的 KMS 节点数量达到该阈值即视为达成共识。该阈值对应 GatewayConfig 文档 中的kmsGenThreshold,要求非零且不超过注册 KMS 节点总数,由 owner 在部署时设定、后期可更新。

此外,共识达成前返回的getConsensusTxSenders列表为空,只有共识达成后才填充参与共识的 KMS 交易发送者地址——这正是测试 gateway-contracts/test/KMSGeneration.ts 中“fresh proxy 上getConsensusTxSenders返回空数组”断言所验证的行为。

读取公共材料:view 函数一览

原文档给出的材料读取语义,在主实现与 Gateway 只读版本中均有对应 view 函数。核心查询接口如下:

函数参数返回值说明
getKeyParamsTypekeyIdParamsType该密钥生成时使用的参数类型(从配对的 prepKeygenId 读取)
getCrsParamsTypecrsIdParamsType该 CRS 生成时使用的参数类型
getConsensusTxSendersrequestIdaddress[]参与该请求共识的 KMS 交易发送者地址
getKeyMaterialskeyId(string[] urls, KeyDigest[] digests)共识节点的存储 URL 列表 + 密钥摘要
getCrsMaterialscrsId(string[] urls, bytes crsDigest)共识节点的存储 URL 列表 + CRS 摘要
getVersionstring合约版本,如KMSGeneration v0.5.0

其中getKeyMaterials/getCrsMaterials返回的 URL 列表,是通过GatewayConfig(Gateway 链)或ProtocolConfig(以太坊)的getKmsNodeForContext(...).storageUrl从共识交易发送者地址反查得到的(见 gateway-contracts/contracts/KMSGeneration.sol)。也就是说,链上并不直接存放密钥或 CRS 二进制本体,只存放材料摘要与存储地址,实际材料由 KMS 节点上传到各自的storageUrl,调用方据此下载。

主实现还额外提供getActiveKeyIdgetActiveCrsIdgetKeyCountergetCrsCountergetCompletedKeyIdsgetCompletedCrsIdsgetKeyInfo等状态查询函数,便于运营者与监控系统跟踪当前生效的密钥/CRS 以及历史完成记录。

链上查询与测试验证

由于 KMSGeneration 已迁移至以太坊,Gateway 链上的 KMSGeneration 只用于历史查询,这一点在合约头注释与接口注释(gateway-contracts/contracts/interfaces/IKMSGeneration.sol)中反复强调:对于最新的密钥、CRS 与协议参数,应查询部署在以太坊上的ProtocolConfigKMSGeneration合约。

针对只读版本的单元测试位于 gateway-contracts/test/KMSGeneration.ts,它通过空代理升级部署合约并验证:

  • getVersion()返回KMSGeneration v0.5.0
  • 对不存在的keyId/crsId调用材料查询时,分别 revert 自定义错误KeyNotGeneratedCrsNotGenerated
  • 未完成请求的getConsensusTxSenders返回空数组。

这些断言直接印证了“只读、历史查询、严格错误处理”的合约语义,也可作为开发者在本地用 Hardhat 复现合约行为的参考用例。

相关合约与延伸阅读

KMSGeneration并非孤立运行,它与以下合约协同构成 fhEVM 的密钥管理闭环:

  • GatewayConfig:登记 KMS 节点元数据(txSenderAddresssignerAddressipAddressstorageUrl)与kmsGenThreshold等阈值,是 KMS 节点身份与材料存储地址的权威来源;
  • ProtocolConfig(以太坊侧):主实现的上下文/epoch 管理、KMS 节点与阈值查询来源;
  • PauserSet:pauser 账户管理,用于暂停相关合约功能。

若需部署或运行 Gateway 合约栈,可继续阅读 本地部署指南、Docker 部署指南 与 环境变量说明;KMS 节点的工程实现可参考 kms-connector 仓库。

总结

KMSGeneration合约是 fhEVM 协议中 FHE 密钥与 CRS 公共材料的“生产调度中枢”:owner 发起请求,KMS 节点以 EIP-712 签名提交结果,按kmsGenThreshold达成共识后激活新材料并通过事件对外广播。掌握其两阶段 keygen 流程、crsgen 流程、全局唯一 ID 编码与上下文固定的共识设计,是理解 fhEVM 密钥生命周期、进行协议运营排查或在此基础上做二次开发的前提。当前仓库中,Gateway 链上的版本已收敛为历史只读查询接口,而完整的生成能力集中在以太坊主实现中,二者配合使用即可覆盖“生成-共识-查询-下载”的完整链路。

【免费下载链接】fhevmFHEVM, a full-stack framework for integrating Fully Homomorphic Encryption (FHE) with blockchain applications项目地址: https://gitcode.com/GitHub_Trending/fh/fhevm

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/12 13:45:27

图片转3D模型完整教程:Hunyuan3D-2 本地部署与首次生成上手

图片转3D模型完整教程:Hunyuan3D-2 本地部署与首次生成上手 【免费下载链接】Hunyuan3D-2 High-Resolution 3D Assets Generation with Large Scale Hunyuan3D Diffusion Models. 项目地址: https://gitcode.com/GitHub_Trending/hu/Hunyuan3D-2 手里有一张角…

作者头像 李华
网站建设 2026/9/12 13:42:39

AI内容检测与降AI率工具全解析

1. 自考备考的AI检测困境解析 近年来,随着在线教育平台和远程考试系统的普及,自考考生在提交作业和论文时,越来越频繁地遇到AI内容检测的困扰。各大院校使用的查重系统如Turnitin、知网等,都陆续加入了AI生成内容识别功能&#xf…

作者头像 李华
网站建设 2026/9/12 13:41:40

5 分钟把写不利的提示词改好:prompt-optimizer 快速上手指南

5 分钟把写不利的提示词改好:prompt-optimizer 快速上手指南 【免费下载链接】prompt-optimizer An AI prompt optimizer for writing better prompts and getting better AI results. 项目地址: https://gitcode.com/GitHub_Trending/pro/prompt-optimizer …

作者头像 李华
网站建设 2026/9/12 13:41:35

NautilusTrader 高精度 128 位与标准 64 位精度模式怎么选?

NautilusTrader 高精度 128 位与标准 64 位精度模式怎么选? 【免费下载链接】nautilus_trader Production-grade Rust-native trading engine with deterministic event-driven architecture 项目地址: https://gitcode.com/GitHub_Trending/na/nautilus_trader …

作者头像 李华