Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: zk shared key #586

Open
wants to merge 24 commits into
base: main
Choose a base branch
from
Open

feat: zk shared key #586

wants to merge 24 commits into from

Conversation

Mikelle
Copy link
Member

@Mikelle Mikelle commented Jan 28, 2025

Describe your changes

Overview of the Changes in PR #586 - Zero-Knowledge Shared Key

Below is a high-level summary of what's going on in this pull request, focusing on the major changes and how they fit together. It’s grouped by core themes:

Doc for the reference: https://www.notion.so/primev/Preventing-Unopenable-Commitments-1606865efd6f8097927ed9c162ea7631


1. Zero-Knowledge (ZK) Context and Proof Flows

New BN128.sol Utility

  • A new file: contracts/contracts/utils/BN128.sol, which provides wrappers for two bn128 precompiles:
    • ecAdd (bn128 addition at 0x06)
    • ecMul (bn128 multiplication at 0x07)
  • If the precompile calls fail, it reverts with BN128AddFailed or BN128MulFailed.

ZK Proof in PreconfManager

  • PreconfManager.sol now:
    • Stores a zkContextHash (like "mev-commit opening <chainID>").
    • Expects an array param _zkProof in openCommitment(...).
    • If the caller is the commitment’s winner (the provider), it calls _verifyZKProof(zkProof).
    • _verifyZKProof(zkProof):
      1. Computes a = g^z * (providerPub)^c
      2. Computes a' = B^z * C^c
      3. Re-hashes these points with zkContextHash → a challenge
      4. Checks that it matches _zkProof’s challenge

ABI Changes

  • PreconfManager.abi & generated Go bindings changed:
    • Old sharedSecretKey in function parameters/events replaced by uint256[] zkProof.
    • New error types: BN128AddFailed, BN128MulFailed, ProviderZKProofInvalid.
  • No more storing “secret key bytes” on-chain; now it’s a ZK approach to prove ephemeral keys.

2. Struct / Signature Layout Changes

Commitment Data

  • Old param sharedSecretKey is removed; each side now supplies an 8-element zkProof array ([providerX, providerY, bidderX, bidderY, sharedX, sharedY, c, z]).

Bid Hash

  • EIP-712 struct for a bid now includes bidder’s BN254 public key:

    PreConfBid(
      string txnHash,
      string revertingTxHashes,
      uint256 bidAmt,
      uint64 blockNumber,
      uint64 decayStartTimeStamp,
      uint64 decayEndTimeStamp,
      uint256 bidderPKx,
      uint256 bidderPKy
    )
  • Go code (e.g. encryptor/encryptor.go) updated to include (bidderPKx, bidderPKy) in ABI-encoded hashing.

Pre-Confirmation Hash

  • Similarly updated from:

    OpenedCommitment(string txnHash, …, bytes sharedSecretKey)

    to

    OpenedCommitment(
      bytes32 bidHash,
      string signature,
      uint256 sharedKeyX,
      uint256 sharedKeyY
    )

3. Go Libraries and BN254 Key Handling

p2p/pkg/crypto/ecdh.go and zkproof.go

  • New ECDH for BN254:
    • GenerateKeyPairBN254()(sk, pk)
    • DeriveSharedKey(skA, pkB) → shared G1 point C.
  • ZK:
    • GenerateOptimizedProof(sk, A, B, C, context)(c, z)
    • VerifyOptimizedProof(proof, A, B, C, context)bool
  • Serialization:
    • BN254PublicKeyToBytes(...) / BN254PublicKeyFromBytes(...) (96 bytes uncompressed).
    • BN254PrivateKeyToBytes(...) / BN254PrivateKeyFromBytes(...) (32 bytes for fr.Element).
  • Key Store:
    • The old P256 ECDH references replaced by BN254 in keysstore.Store:
      • SetBN254PrivateKey(...), GetBN254PrivateKey(...)
      • SetBN254PublicKey(...), GetBN254PublicKey(...)

4. Effects on the P2P Side

  • The handshake in p2p/pkg/p2p/libp2p/internal/handshake/ now exchanges BN254 public keys instead of ECDH P256.
  • Keys struct in p2p/pkg/p2p/p2p.go changed:
    • NIKEPublicKey*bn254.G1Affine (was *ecdh.PublicKey).
    • Corresponding JSON marshalling logic updated for 96-byte BN254 format.

5. Contract and Storage Adjustments

  • PreconfManager:
    • openCommitment(...) → final param _zkProof.
    • If msg.sender == winner, calls _verifyZKProof(_zkProof).
    • Reverts with ProviderZKProofInvalid if verification fails.
    • Removes references to sharedSecretKey in events.
  • Less On-Chain Data: ephemeral key is no longer stored as raw bytes in events.

6. Typical Flow

  1. Bidder includes its BN254 public key (PKb) in EIP-712 bid signature.
  2. Provider sees (PKb), computes shared secret C = PKb^skProvider, and generates a ZK proof (c,z) for that ephemeral secret.
  3. Provider calls openCommitment(…, _zkProof).
  4. Contract verifies _verifyZKProof(...).
  5. If valid, on-chain logic accepts the provider’s ephemeral key.

7. Summary

  • Replaces a simple sharedSecretKey bytes approach with BN254 ECDH + zero-knowledge proof to ensure the ephemeral key is valid, without exposing it.
  • Affects:
    • On-chain: new ZK logic, updated ABIs, no more plain ephemeral secret in events.
    • Off-chain: new BN254-based ECDH library, updated key store, handshake, EIP-712 hashing.

Checklist before requesting a review

  • I have added tests that prove my fix is effective or that my feature works
  • I have made corresponding changes to the documentation

@Mikelle Mikelle self-assigned this Jan 28, 2025
@Mikelle Mikelle marked this pull request as ready for review January 30, 2025 14:49
@Mikelle Mikelle requested a review from chrmatt January 30, 2025 16:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant