Fhenix
概要
Fhenix自体はブロックチェーンで、fhEVMというFHEを搭載したEVM?つまり暗号化したまま計算可能なEVMを搭載している 開発者はいつも通りsolidityでConfidential Smart Contractsを作成できる。
Fhenixはモジュール化されており、ブロックチェーンのL1でもL2でもないと自己定義している。
全てのブロックチェーンに対して統合可能なFHE拡張というべき?
fhEVMはZamaが開発していたものを統合したらしい。
FHEを用いたPIRが可能だとすれば
FHE Rollup
FHE+ORUを組み合わせたFHE-Rollupを提案している
シーケンサー、バリデーター、DAレイヤーを分離している。
イーサリアムはsettlementとDAコンポーネントを処理し、Fhenixはシーケンサー(実行)とバリデーター(トランザクション検証)を処理する。
このコンポーネントの分離によりFHE RollupsはイーサリアムのDAに必要なアクセスを持ちながら、より効率的に実行できる
That means that dApps running on (or using) Fhenix will be able to integrate encrypted data in their smart contract logic. Developers will have the choice to decide what will be encrypted and what will remain plaintext.
FHEosがスマコンにFHEプリミティブの機能を付与する
https://scrapbox.io/files/656e80bf89baa900239ec524.png
高価なFHE計算をすべてのノードで複製するコストを回避するためにORUベースにしているらしい。
At a high level, we ensure data integrity by running a variation of Arbitrum Nitro’s fraud prover, which can do fraud proofs over the WebAssembly Virtual Machine (WASM). This has allowed us to compile FHE logic to WebAssembly and run it in a secure way on WASM code, rather than on the native Ethereum Virtual Machine (EVM) itself. Without using Arbitrum Nitro’s fraud prover, there would be challenges given that Ethereum does not natively support FHE operations.
Threshold Services Network (TSN)
FHEにおける復号化には秘密鍵が必要だが、これを分散管理するために秘密分散法に基づいて実装されたTSNが用意されている 流れとして、まずユーザーは暗号化された情報をFHE Rollup上に配置されるコントラクトに投げる。これをfheOSで秘密計算し、その結果を復号するためにTSNを用いる。
例えば以下のように投票結果を発表する際に票を集計し、TSNはデータを復号して返す
https://scrapbox.io/files/656eaf8339bc7a002438af8f.png
Currently, state of the art zero-knowledge proofs of knowledge (ZKPoK) over FHE ciphertexts 30 are still relatively expensive, and would add a non-trivial amount of overhead to each transaction. One alternative would be to have clients start by secret-sharing their secret inputs to the TSN using a verifiable secret-sharing protocol (VSS) 18. After confirming that the inputs have been properly secret-shared, the network can jointly encrypt the inputs, for example, by the following simplified protocol sketch. TSNはre-encryptionにも使用され、暗号化されたデータを別の暗号鍵を使用して再度暗号化することができる。
これにより、元の暗号化されたデータのセキュリティを維持しながら、新しい暗号鍵によるアクセス制御やデータの共有が可能になる。
秘密の共有データに関する証明
特定のケースでは、暗号化されたデータに関する重要な記述を証明するために、 TSNを活用することができるかもしれない
暗号文は整形されている必要があり、整形されていな暗号文を復号しようとすると秘密鍵に関する情報が漏れる可能性がある
暗号化し ていない暗号文を送信し、TSNにその暗号文の復号化を依頼していないことを保証する 必要がある。
これらの理由から、ユーザが暗号化された入力を送信するときは常に、それが適切に暗号化され、ユーザがその基礎となる平文を知っていることを確認する必要がある。
入力が適切に秘密共有されたことを確認した後、ネットワークは入力 を共同で暗号化することができる。
https://scrapbox.io/files/656ec6cf92766f00232ee58a.png
つまりFhenixで用いられる秘密分散法(VSS)の目的は
FHEの秘密鍵(復号鍵)を分散管理するため
zkPoKの代替として秘密の共有データが正しいことを証明する
zkFHEはこれをzkで解決
TFHE(FHE over the Torus)
ブロックチェーンは主に整数演算を扱うため、TFHEが暗号化された形で整数の計算を効率的に処理できるという特徴は嬉しい。
さらに、ほとんどのブロックチェーンは、多数の複雑な整数ベースの計算を伴うコンセンサスメカニズムで動作している。これらの演算を迅速かつ効率的に処理できるTFHEの能力は、ブロックチェーン全体のパフォーマンスを大幅に向上させ、計算のボトルネックを減らすことができる。ブロックチェーンの規模が拡大し、取引量やスマートコントラクトの複雑さが増すにつれて、この効率性は極めて重要になる。
Fhenix上で署名作成する方法とEVM上でそれを検証する方法
FHE署名onスマコンはECDSA.solみたいなコントラクトをTFHE.solでラップすれば実装できると思う。
あとはfhEVM(sequencer,Validator)に渡してL1に流れればEVM上でecrecoverを使って検証が可能になるはず。
code: (mermaid)
sequenceDiagram
participant User
participant fhEVM
participant Ethereum
User->>fhEVM: トランザクション生成
fhEVM->>User: 署名されたトランザクション
Note right of User: ユーザーは署名を取得
User->>Ethereum: 署名されたトランザクション転送
Note over Ethereum: トランザクションの検証
Ethereum->>Ethereum: ecrecoverを使用して署名検証
Ethereum-->>User: 検証結果
これらの暗号化された変数(Encrypted Types)をチェーンに送信するには、まずデータを FhenixJS/fhevmJS を使ってチェーンの外で暗号化され、これらの値はバイト配列として表現され、この形式でコントラクトに送信される。
return
ユーザーがデータへのアクセスを許可されていると判断したら、TFHE.reencrypt関数を使用してデータを返す準備をする。この関数は、指定されたユーザーだけが復号化できる特別な方法でデータを暗号化する。
事実上、ユーザーの公開鍵を使ってデータを「再暗号化」し、(対応する秘密鍵を持つ)受信者だけがデータを解読できるようにす。
暗号化された情報なのでif/elseとかできなくね?
code:j
euint32 a = TFHE.asEuint32(10);
euint32 b = TFHE.asEuint32(20);
if (TFHE.lt(a, b)) {
return TFHE.reencrypt(a);
} else {
return TFHE.reencrypt(b);
}
そこでcmuxという論理演算を使うらしい。具体的には参考文献を参照.
裏側のロジックは複雑だがメソッドは容易に呼び出される。
code:cmux
ebool isHigher = TFHE.lt(existingBid, value);
bidsmsg.sender = TFHE.cmux(isHigher, value, existingBid); requireもこれを応用して実装されているが、暗号化されたデータへの計算コストは膨らむ。
そこでoptimistic require という関数の実行が終わるまで条件の評価を延期することを可能にし、FHEコントラクトで条件を扱うより効率的な方法を提供している。
code:optimistic_req
euint32 a = TFHE.asEuint32(some_encrypted_value);
euint32 b = TFHE.asEuint32(some_other_encrypted_value);
TFHE.optReq(TFHE.le(a, b));
// some operations...
すべての条件が関数の最後で評価されるため各ステップの後に一時停止してチェックする必要がなく実行速度が速くなるが、条件が満たされない場合、必要ないかもしれない計算が可能になるためより多くのガスを消費する可能性があります。
機密性を持ったままユーザーのアクセスをコントロールする
アクセス制御はeencrypt functionによって行われ、意図された受信者だけが復号化してデータを閲覧できるようにデータを再暗号化している。このアプローチにより、暗号化されたデータは機密性を保ち、許可されたユーザーのみがアクセスできるようになる。
通常、Solidity コントラクトは View 関数を使用してデータを公開する。なぜなら、ビュー関数には、呼び出し元が本人であることをコントラクトが暗号的に検証するためのメカニズムが付属していないから。
つまり、誰がデータにアクセスできて、誰ができないかをコントラクトが判断できるような仕組みを作らなければならない。
受信者が認証されているかどうかを確認するために、EIP712署名が採用されている。これにより、あるデータの署名者が彼らが主張するアカウントの所有者であることを確認することができる。
例を使ってこのコンセプトを実際に見てみよう。暗号化されたERC20トークンコントラクトにおいて、ユーザーがトークンの残高を照会したいとします。残高は暗号化されたデータとして保存されているため、コントラクトは情報を公開する前に、その問い合わせが本当にトークン所有者からのものであることを確認する必要があります。ここでEIP712署名が登場します。
code:eip712
function balanceOf(
bytes32 publicKey,
bytes calldata signature
)
public
view
onlySignedPublicKey(publicKey, signature)
returns (bytes memory)
{
return TFHE.reencrypt(balancesmsg.sender, publicKey); }
この関数の onlySignedPublicKey は、EIP712 署名が有効かどうかを検証する修飾子である。署名が呼び出しを行うアカウント(msg.sender)に対応していれば、関数は実行される。そうでない場合は、関数は元に戻ります。
onlySignedPublicKey修飾子は以下のようになります:
code:j
modifier onlySignedPublicKey(bytes32 publicKey, bytes memory signature) {
bytes32 digest = _hashTypedDataV4(
keccak256(
abi.encode(keccak256("Reencrypt(bytes32 publicKey)"), publicKey)
)
);
address signer = ECDSA.recover(digest, signature);
require(
signer == msg.sender,
"EIP712 signer and transaction signer do not match"
);
_;
}
onlySignedPublicKey修飾子は公開鍵と署名を受け取ります。そして公開鍵からダイジェストを計算する。署名者のアドレスは、ECDSA.recover関数を使用してダイジェストから復元される。復元されたアドレスがmsg.senderと一致すれば、呼び出し元が確かにアカウントの所有者であり、データへのアクセスが許可されていることを意味する。
fhEVM solidityライブラリには、上記のスニペットを含むヘルパー・コントラクトEIP712WithModifier.solが付属しており、簡単にインポートしてコントラクトに統合することができます。EncryptedERC20.solを参照してください。
参考文献
FHE周りのライブラリはRustで書かれており、gethと都合を合わせるためにラッパーやFFI実装が色々と用意されている。