Match Validity Circuit

Match Validity Circuit

Constraint Logic for Bidirectional Intent Symmetry

At the core of SnarkSide’s private perpetual matching architecture is the Match Validity Circuit — a zero-knowledge proof circuit designed to validate the compatibility of two encrypted trade intents while preserving bidirectional symmetry, constraint satisfaction, and user anonymity.

This circuit ensures that a pair of matched intents satisfy all trading constraints (size, slippage, direction, expiry, collateral) without revealing any sensitive trade information. It verifies the internal soundness of both intents, their agreement as a trading pair, and that the result of their match is cryptographically deterministic.

This document explores the technical underpinnings of the Match Validity Circuit, including its symmetric constraint system, Poseidon commitment structure, and output guarantees.


Purpose

The Match Validity Circuit enforces that:

  • Both submitted intents are individually valid.

  • The intents are complementary: one long, one short.

  • Their notional sizes fall within a defined match window (ε tolerance).

  • Their slippage windows are compatible for execution.

  • Their expiry windows are valid at match time.

  • Both nullifiers are distinct and unused.

  • The final match_commitment hash is symmetric and non-malleable.

It is the central cryptographic mechanism for trustless, invisible counterparty resolution in SnarkSide.


Symmetric Intent Compatibility

Since SnarkSide intentionally avoids wallet-based identities, addresses, or transaction sequencing, intent matching must be symmetric — either party in the match could have submitted first, and the outcome should not change. The circuit must:

  • Treat (IntentA, IntentB) and (IntentB, IntentA) as functionally identical.

  • Canonicalize intent ordering internally using deterministic logic.

  • Prevent proof manipulation through reordering.

To accomplish this, all hash commitments in the circuit are generated with sorted inputs:

signal input intent_commitment_A;
signal input intent_commitment_B;

component ordering = Comparator(2);
ordering.in[0] <== intent_commitment_A;
ordering.in[1] <== intent_commitment_B;

signal lower = ordering.out[0];
signal higher = ordering.out[1];

component matchHasher = Poseidon(3);
matchHasher.inputs[0] <== lower;
matchHasher.inputs[1] <== higher;
matchHasher.inputs[2] <== match_salt;

match_commitment <== matchHasher.output;

This ensures ordering-invariant proof generation.


Constraint Logic

Inputs

  • intent_commitment_A, intent_commitment_B

  • nullifier_A, nullifier_B

  • direction_A, direction_B (0 = short, 1 = long)

  • notional_A, notional_B

  • slippage_A, slippage_B

  • expiry_A, expiry_B

  • vault_commitment_A, vault_commitment_B

  • match_salt

Core Constraints

1. Opposite Trade Directions

signal direction_diff;
direction_diff <== direction_A + direction_B;
assert(direction_diff == 1);

Enforces one long, one short.

2. Notional Compatibility

signal size_diff;
size_diff <== abs(notional_A - notional_B);
assert(size_diff <= MAX_SIZE_DELTA);

Allows matching intents within ±ε units of each other.

3. Slippage Compatibility

// Slippage is interpreted as price buffer tolerance
signal price_A = notional_A / (1 + slippage_A);
signal price_B = notional_B / (1 - slippage_B);
assert(price_A <= price_B);

Ensures mutual price tolerance agreement.

4. Expiry Validity

signal current_block;  // Injected externally
assert(expiry_A >= current_block);
assert(expiry_B >= current_block);

Verifies both intents are still valid at match time.

5. Distinct Nullifiers

assert(nullifier_A != nullifier_B);

Protects against self-matching or replay.

6. Vault Binding (Optional for Settlement Circuit)

If vaults are committed into the match circuit, we enforce margin validity:

component vault_hash_A = Poseidon(2);
vault_hash_A.inputs[0] <== margin_root;
vault_hash_A.inputs[1] <== vault_commitment_A;

assert(vault_hash_A.output == committed_margin_hash_A);

This ensures user funds are valid and committed before match.


Match Commitment Generation

Final output from the circuit is a match commitment hash used as the trade identifier:

match_commitment = Poseidon(
  min(intent_commitment_A, intent_commitment_B),
  max(intent_commitment_A, intent_commitment_B),
  match_salt
)

This is the only public signal required to settle the trade. It contains no user data and is impossible to reverse.


Output Signals

The circuit produces:

  • match_commitment: Poseidon hash used on-chain

  • nullifier_A, nullifier_B: published and burned at settlement

  • proof: Groth16 artifact that proves all constraints above

No size, slippage, leverage, or user metadata is included on-chain.


Summary

The Match Validity Circuit in SnarkSide is the cryptographic equivalent of a perpetual futures matching engine — but with:

  • No orderbook

  • No visibility

  • No leakage

  • No trust assumptions

It defines the rules of trade resolution in pure logic, enforced by SNARKs and validated publicly. All matching is privacy-preserving, constraint-bound, and symmetric — a radical reimagination of what it means to match orders in a decentralized world.

Last updated