
fhEVM 加密类型运算全指南FHE 库算术、位运算、比较、三元选择与随机数操作【免费下载链接】fhevmFHEVM, a full-stack framework for integrating Fully Homomorphic Encryption (FHE) with blockchain applications项目地址: https://gitcode.com/GitHub_Trending/fh/fhevm本篇技术指南系统梳理 fhEVM 开源项目中 FHE 库 对加密整数类型euintX与ebool支持的全部运算能力覆盖算术、位运算、比较、三元选择与链上随机数生成并给出可直接落地的最佳实践。读完本文你将掌握在 Solidity 智能合约中安全、省 gas 地操作 FHE 密文的完整 API 清单与底层实现原理能够独立写出正确且防溢出的隐私计算合约。加密类型运算全景从 FHE 库到 FHEVMExecutor在 fhEVM 中密文以 256 位 ciphertext handle 的形式存在于链上FHE.sol 通过重载为每种加密类型ebool、euint8euint256提供类型安全的封装函数。从源码结构看这些封装最终都会收敛到 Impl.sol 中一组对IFHEVMExecutor的调用——例如FHE.add内部实际调用fheAddFHE.select内部调用fheIfThenElse// library-solidity/lib/Impl.sol (L519-L527) function add(bytes32 lhs, bytes32 rhs, bool scalar) internal returns (bytes32 result) { bytes1 scalarByte; if (scalar) { scalarByte 0x01; } else { scalarByte 0x00; } CoprocessorConfig storage $ getCoprocessorConfig(); result IFHEVMExecutor($.CoprocessorAddress).fheAdd(lhs, rhs, scalarByte); }值得注意的细节是绝大多数二元运算add/sub/mul/and/or/xor/shl/shr/rotl/rotr/eq/ne/ge/gt/le/lt/min/max都带有一个bool scalar参数用于标记第二个操作数是否为未加密的标量而 div 与 rem 的实现中该值被硬编码为0x01即只允许明文除数详见下文算术运算小节。这一层抽象正是「同一种运算既有密文-密文版本、又有密文-标量版本」的底层来源也是 gas 优化Best Practices 小节的关键依据。算术运算FHE库对加密整数euintX支持以下算术操作名称函数名符号类型加法FHE.add二元减法FHE.sub-二元乘法FHE.mul*二元除法明文除数FHE.div二元取余明文除数FHE.rem二元取负FHE.neg-一元最小值FHE.min二元最大值FHE.max二元注意除法FHE.div与取余FHE.rem目前仅支持明文除数plaintext divisor。这一点在 types.md 中也有说明若将加密值作为右操作数rhs传入div/rem会触发 panic。从 Impl.sol 源码可以看到fheDiv与fheRem的scalarByte恒为0x01从实现层面印证了这一限制。FHE.add、FHE.sub、FHE.mul、FHE.min、FHE.max等函数在 FHE.sol 中针对每种位宽8/16/32/64/128/256以及跨位宽组合如euint8 euint64 → euint64都提供了重载版本返回值位宽自动取两者中较大者。此外除neg一元外的每个运算都有对应的标量版本例如 FHE.add(euint8 a, uint8 b)这为最佳实践中的 gas 优化提供了接口基础。位运算FHE库还支持包括移位与循环移位在内的位运算名称函数名符号类型按位与FHE.and二元按位或FHE.or\|二元按位异或FHE.xor^二元按位取反FHE.not~一元右移FHE.shr二元左移FHE.shl二元循环右移FHE.rotr二元循环左移FHE.rotl二元移位操作的取模语义与 Solidity 原生位移的关键差异移位操作符FHE.shr与FHE.shl的第一个操作数可以是任意加密类型euintX第二个操作数可以是uint8或euint8但第二个操作数始终按第一个操作数的位数取模。例如FHE.shr(euint64 x, 70) // 等价于 FHE.shr(euint64 x, 6)因为 70 % 64 6这与 Solidity 原生移位操作符有本质区别原生不进行中间取模例如任意uint64右移 70 位会直接得到 0。因此编写 fhEVM 合约时不能照搬 Solidity 的移位直觉——FHE.shr/FHE.shl的移位量先被缩减到[0, bitWidth-1]区间循环移位FHE.rotl/FHE.rotr同样遵循该语义。比较运算加密整数之间可以通过以下函数进行比较所有比较函数的返回值都是ebool加密布尔值因此比较结果本身也是密文、不泄露任何明文信息名称函数名符号类型等于FHE.eq二元不等于FHE.ne二元大于等于FHE.ge二元大于FHE.gt二元小于等于FHE.le二元小于FHE.lt二元在 Impl.sol 中这六个比较操作分别映射到FHEVMExecutor的fheEq/fheNe/fheGe/fheGt/fheLe/fheLt并同样支持标量scalar版本。比较结果是ebool这正是接下来FHE.select三元操作的天然控制条件也是防溢出逻辑见最佳实践的基本构件。三元操作FHE.selectFHE.select是一个三元操作根据加密条件在两个加密值之间二选一名称函数名符号类型选择FHE.select三元其签名模式为FHE.select(ebool control, T ifTrue, T ifFalse)控制条件、两个分支及返回值都是密文。FHE.sol 为ebool、euint8euint256乃至eaddress都提供了重载底层实现在 Impl.sol 中// 若 control 的值为 true结果等于 ifTrue否则结果等于 ifFalse function select(bytes32 control, bytes32 ifTrue, bytes32 ifFalse) internal returns (bytes32 result) { CoprocessorConfig storage $ getCoprocessorConfig(); result IFHEVMExecutor($.CoprocessorAddress).fheIfThenElse(control, ifTrue, ifFalse); }FHE.select是 fhEVM 中实现「密文分支逻辑」的核心手段——由于无法对密文直接if/else任何需要根据加密条件改变数据流的场景如防溢出回退、条件授权、限额控制都要借助它。仓库中的 EncryptedERC20.sol 就大量使用FHE.select实现可转移性控制与限额扣减。随机操作链上加密随机数FHE库支持完全在链上生成密码学安全的随机加密数且随机数保持加密状态名称函数名符号类型随机无符号整数FHE.randEuintX()随机完整的随机数用法、安全注意事项与有界随机数细节参见 Generate random numbers随机加密数生成。此处概括其要点必须在交易中执行随机数生成需要链上更新伪随机数生成器PRNG状态因此不能通过eth_callRPC 方法调用。支持的位宽FHE.randEbool()、FHE.randEuint8()、FHE.randEuint16()、FHE.randEuint32()、FHE.randEuint64()、FHE.randEuint128()、FHE.randEuint256()。有界随机数可传入上界upperBound必须是 2 的幂生成区间为[0, upperBound - 1]例如FHE.randEuint8(32)生成 0~31 的随机数。从 FHE.sol 源码看无界版本调用Impl.rand(FheType)有界版本调用Impl.randBounded(upperBound, FheType)每种位宽均有对应实现。仓库还提供了完整可运行的示例合约 Rand.sol其中generate8()、generate16UpperBound(uint16)、generate64Reverting()等函数演示了如何生成并存储各类型随机密文以及FHE.allowThis(...)的授权调用可直接作为编写随机数合约的参考模板。最佳实践写出正确且省 gas 的加密合约使用合适的加密类型大小尽量选择能容纳数据的最小加密类型以优化 gas 成本。例如对于 0~255 的小数值应使用euint8而非euint256。❌ 避免使用过大类型// Bad为小数值使用过大的加密类型浪费 gas euint128 age FHE.asEuint128(25); // age 永远不会超过 255 euint128 percentage FHE.asEuint128(75); // percentage 取值 0-100✅ 改用最合适的小类型// Good使用合适大小的类型 euint8 age FHE.asEuint8(25); // 8 位即可容纳 euint8 percentage FHE.asEuint8(75); // 8 位即可容纳注类型声明的位宽必须与转换函数返回的位宽一致例如声明euint8 age就应使用FHE.asEuint8(25)。尽可能使用标量操作数以节省 gas部分 FHE 运算符存在两个版本一个版本所有操作数都是密文 handle另一个版本其中一个操作数是未加密的标量。只要场景允许应优先使用标量版本因为密文-标量运算会节省大量 gas。❌ 例如下面这段代码消耗的 gas 明显更多euint32 x; // ... x FHE.add(x, FHE.asEuint32(42));✅ 而下面这段则更省euint32 x; // ... x FHE.add(x, 42);两者最终得到完全相同的加密结果底层对应 Impl.sol 中scalartrue/false两种路径只是标量版本省去了FHE.asEuint32(...)的一次额外密文生成与后续同态计算开销。警惕 FHE 算术运算的溢出FHE 算术运算符会发生溢出。在实现 fhEVM 智能合约时必须把这种可能性考虑进去。需要说明的是fhEVM 的加密整数运算在设计上就是unchecked环绕的——如 types.md 所述这是为了避免通过错误检测泄露操作数信息、保证机密性。❌ 例如如果要为带加密totalSupply状态变量的加密 ERC20 代币编写 mint 函数下面的代码就存在溢出漏洞function mint(externalEuint32 encryptedAmount, bytes calldata inputProof) public { euint32 mintedAmount FHE.fromExternal(encryptedAmount, inputProof); totalSupply FHE.add(totalSupply, mintedAmount); balances[msg.sender] FHE.add(balances[msg.sender], mintedAmount); FHE.allowThis(balances[msg.sender]); FHE.allow(balances[msg.sender], msg.sender); }✅ 可以使用FHE.select在发生溢出时取消铸造来修复该问题function mint(externalEuint32 encryptedAmount, bytes calldata inputProof) public { euint32 mintedAmount FHE.fromExternal(encryptedAmount, inputProof); euint32 tempTotalSupply FHE.add(totalSupply, mintedAmount); ebool isOverflow FHE.lt(tempTotalSupply, totalSupply); totalSupply FHE.select(isOverflow, totalSupply, tempTotalSupply); euint32 tempBalanceOf FHE.add(balances[msg.sender], mintedAmount); balances[msg.sender] FHE.select(isOverflow, balances[msg.sender], tempBalanceOf); FHE.allowThis(balances[msg.sender]); FHE.allow(balances[msg.sender], msg.sender); }这里的核心技巧是由于totalSupply是所有用户余额之和若totalSupply未溢出则balances[msg.sender]也绝不会单独溢出单个余额必然小于等于总和因此只需在totalSupply上单独做溢出检测再通过FHE.lt得到加密的溢出标志isOverflow最后用FHE.select在「保留原值」与「采用新值」之间密文化地选择即可既保证正确性又不泄露任何明文信息。延伸阅读加密类型的完整清单、位宽与各类型支持的运算符矩阵参见 Supported types加密类型支持明文与密文之间转换FHE.asEbool/asEuintXX/asEaddress以及加密类型互转的规则参见 Casting and trivial encryption类型转换与平凡加密有界随机数、安全性与 gas 注意事项的完整说明参见 Generate random numbers随机加密数生成想看到这些运算在完整业务合约中的组合运用可直接阅读 EncryptedERC20.sol 与 Rand.sol 两个示例合约。【免费下载链接】fhevmFHEVM, a full-stack framework for integrating Fully Homomorphic Encryption (FHE) with blockchain applications项目地址: https://gitcode.com/GitHub_Trending/fh/fhevm创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考