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
SingletonZKMultiSigEcdsaSingleton contains ERC-1271 validation logic and delegates proof verification through ERC-8039.
ProxyA minimal account-specific proxy stores the state root and verifier address, then delegates execution to the singleton.
FactoryThe factory validates the initial private-state proof and deploys deterministic proxies with CREATE2.
Verifier adaptersAdapters expose HONK, Groth16, PLONK, or other proof systems through one verification interface.
Transaction flow
- Commit the policy. Build a Merkle tree from the private signer set and threshold, then derive the public state root.
- Deploy the account. Generate a state-validity proof and let the factory deploy the proxy after verification.
- Collect approvals. The required signers sign the transaction hash off-chain.
- Prove authorization. The Noir circuit verifies ECDSA signatures, membership, uniqueness, and the threshold.
- 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_signerECDSA address recovery and single-signer authorization inside a zero-knowledge proof.
zk_labelsPrivate identity and role labels committed to a Poseidon Merkle tree.
zk_multisigM-of-N threshold validation with hidden signer identities and private policy parameters.
zk_scopeProgrammable 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
- Choose a primitive and construct its private state tree.
- Commit the resulting root to the smart account or module.
- Build circuit inputs and generate the proof off-chain.
- Encode public signals and proof bytes for the account call.
- 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 authenticationProve valid signatures or thresholds while hiding the signer set.
Private policiesEnforce limits, timelocks, destinations, and other rules without publishing the policy.
Confidential recoveryValidate a recovery condition while protecting guardians and recovery mechanisms.
Verifier portabilityUse HONK, Groth16, PLONK, SP1, or another system behind the same interface.
Verification contract
- The account defines the expected proof type and public-signal format.
- The caller submits public signals and opaque proof bytes.
- The ERC-8039 verifier validates the proof using its chosen backend.
- 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
- Define private state. Build the signer, label, multisig, or scope tree locally and retain the witnesses off-chain.
- Install the commitment. Configure the account module with the root and its ERC-8039 verifier address.
- Prepare the operation. Bind the proof to the account, chain, nonce, and transaction or user-operation hash.
- Generate the proof. Run Noir and Barretenberg in the client or a trusted proving environment.
- Encode validation data. Package the public signals and proof bytes in the format expected by the module.
- 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 ↗