Microchain
Labs
Developer documentationBack to studio ↗

Protocol · privacy-preserving authorization

zk-multi-signers

A privacy-preserving multisignature smart-account protocol. It proves that an M-of-N approval policy was satisfied while keeping the signer set, threshold, and signing pattern private.

EthereumNoirERC-1271ERC-8039

Overview

The account stores one public commitment, the stateRoot. Authorized signers approve a transaction off-chain, then a zero-knowledge proof demonstrates that enough valid signatures came from members of the committed signer set. On-chain contracts learn that the policy passed and nothing about the identities behind it.

Core architecture

Singleton

ZKMultiSigEcdsaSingleton contains ERC-1271 validation logic and delegates proof verification through ERC-8039.

Proxy

A minimal account-specific proxy stores the state root and verifier address, then delegates execution to the singleton.

Factory

The factory validates the initial private-state proof and deploys deterministic proxies with CREATE2.

Verifier adapters

Adapters expose HONK, Groth16, PLONK, or other proof systems through one verification interface.

Transaction flow

  1. Commit the policy. Build a Merkle tree from the private signer set and threshold, then derive the public state root.
  2. Deploy the account. Generate a state-validity proof and let the factory deploy the proxy after verification.
  3. Collect approvals. The required signers sign the transaction hash off-chain.
  4. Prove authorization. The Noir circuit verifies ECDSA signatures, membership, uniqueness, and the threshold.
  5. Execute. Submit the transaction and proof. ERC-1271 validation succeeds after the ERC-8039 verifier returns its magic value.

State commitment

stateRoot = MerkleRoot([
  signersMerkleRoot,
  Poseidon(threshold)
])

The transaction circuit exposes only the transaction hash and state root as public inputs. Signers, signatures, membership paths, and threshold remain private witnesses.

Install and test

git clone https://github.com/MicrochainLabs/microchain-zk-signers.git
cd microchain-zk-signers
forge install
pnpm install

cd noir && nargo compile && cd ..
npx hardhat compile
npx hardhat test

Prerequisites: Node.js 18 or later, pnpm, Foundry, Nargo, and the Barretenberg bb CLI.

Read the source repository

Circuit toolkit · composable account logic

zk-smart-account-kit

Composable Noir primitives for privacy-preserving identity, threshold signatures, and programmable transaction policies inside smart accounts.

Noir workspaceSafeNexus / ERC-7579ERC-8039

Why it exists

Conventional smart-account authorization publishes signer addresses, approval thresholds, and policy rules. The kit moves that logic into zero-knowledge circuits. The account stores a cryptographic commitment and verifies that a private authorization rule passed.

Primitive library

zk_signer

ECDSA address recovery and single-signer authorization inside a zero-knowledge proof.

zk_labels

Private identity and role labels committed to a Poseidon Merkle tree.

zk_multisig

M-of-N threshold validation with hidden signer identities and private policy parameters.

zk_scope

Programmable access control for targets, function selectors, value limits, and calldata constraints.

Repository structure

zk-smart-account-kit/
├── Nargo.toml
├── lib/
│   ├── zk_signer/
│   ├── zk_labels/
│   ├── zk_multisig/
│   └── zk_scope/
└── noir/

Integration model

  1. Choose a primitive and construct its private state tree.
  2. Commit the resulting root to the smart account or module.
  3. Build circuit inputs and generate the proof off-chain.
  4. Encode public signals and proof bytes for the account call.
  5. Verify through an ERC-8039-compatible verifier before execution.
Explore the circuit toolkit

Ethereum standard · proof verification

ERC-8039

A proof-system-agnostic interface for smart accounts to verify zero-knowledge proofs on-chain and program account logic with ZK circuits.

Standards TrackAccount AbstractionZK proofsDiscussion

The interface

ERC-8039 gives accounts and modules one stable contract boundary for different proving systems. Authentication, authorization, recovery, and policy logic can evolve without coupling the account to a specific verifier implementation.

interface IERC8039 {
  function verifyProof(
    bytes calldata publicSignals,
    bytes calldata proof
  ) external view returns (bytes4 magicValue);

  function getProofType() external view returns (bytes32);
  function metadata() external view returns (string memory);
}

What it enables

Private authentication

Prove valid signatures or thresholds while hiding the signer set.

Private policies

Enforce limits, timelocks, destinations, and other rules without publishing the policy.

Confidential recovery

Validate a recovery condition while protecting guardians and recovery mechanisms.

Verifier portability

Use HONK, Groth16, PLONK, SP1, or another system behind the same interface.

Verification contract

  1. The account defines the expected proof type and public-signal format.
  2. The caller submits public signals and opaque proof bytes.
  3. The ERC-8039 verifier validates the proof using its chosen backend.
  4. A valid call returns the standard magic value; every other result fails closed.
Read the full ERC-8039 proposal

Guide · application architecture

Smart Account Integration

Connect a private authorization circuit to a Safe or ERC-7579-compatible account through a small, auditable verification boundary.

ClientProverModuleVerifier

Integration path

  1. Define private state. Build the signer, label, multisig, or scope tree locally and retain the witnesses off-chain.
  2. Install the commitment. Configure the account module with the root and its ERC-8039 verifier address.
  3. Prepare the operation. Bind the proof to the account, chain, nonce, and transaction or user-operation hash.
  4. Generate the proof. Run Noir and Barretenberg in the client or a trusted proving environment.
  5. Encode validation data. Package the public signals and proof bytes in the format expected by the module.
  6. Verify and execute. The account calls verifyProof, checks the magic value, and continues after validation.

Trust boundary

private witnesses
      ↓
client / prover ── proof + signals ──▶ smart account
                                           ↓
                                    ERC-8039 verifier
                                           ↓
                                       execution

The verifier should bind every proof to its intended account context. Domain separation, chain ID, nonce, and operation hash prevent replay in another account or transaction.

Production checklist

□ Pin circuit and verification-key versions.

□ Validate public-signal length and ordering.

□ Bind proofs to chain, account, nonce, and call data.

□ Reject unknown proof types and return values.

□ Test state rotation and recovery paths.

□ Audit witness construction and encoding.

Start from the toolkit