How Enygma works

This page explains how an Enygma payment moves from one Rayls Sovereign chain to another, and what the Private Network Hub records along the way. The Hub is the Hyperledger Besu chain at the centre of every Rayls Private Network, and every Enygma transfer settles on it. For the parties involved and what each can see, read Who sees what next.

The building blocks

Balances are commitments on the Hub

Each participant (an institution with its own Rayls Sovereign chain) has one balance per Enygma token on the Hub. The Hub stores it as a Pedersen commitment: a single elliptic-curve point that hides the amount but can be added to other commitments. Enygma payments therefore use an account-based model: a transfer updates each participant's running balance, rather than spending and creating individual coins.

Inside each institution's own chain, the same token is an ordinary ERC-20 balance per client. Enygma only applies when value moves between chains.

A transfer is a zero-sum set of commitments

An Enygma transaction adds one new commitment to the balance of each participant in the transaction:

  • the sender's commitment is negative, for the total it sends;
  • each receiver's commitment is positive, for what it receives;
  • the other participants receive a commitment to zero.

All of these commitments add up to zero, so no value is created or destroyed. A zero-knowledge proof attached to the transaction shows that, and also that the sender knows its keys and its previous balance, that it can afford the transfer, and that the transaction's nullifier and message tags are correctly formed. The Hub checks the proof without seeing any amount.

The anonymity set

Every Enygma transaction names a fixed number of participants, k, from 2 to 6. The relayer sets k to the number of participants in the network, capped at six, and fills the set with randomly chosen participants who receive zero. Observers can see which k participants were in a transaction, but not which of them received value, or how much.

The sender is not hidden in the same way. Each participant's relayer submits its transactions to the Hub from that participant's own account, so anyone who can read the Hub can tell which participant sent each transaction.

How much this hides depends on the size of the network. See Who sees what.

Shared secrets and message tags

When an institution joins the network, it agrees a shared secret with every other participant, using ML-KEM, a post-quantum key exchange. These secrets serve two purposes:

  • they derive the random factors inside each commitment, so the commitments in a transaction cancel out exactly;
  • they derive a message tag for each participant, which lets a receiver recognise the messages meant for it.

Each transaction also carries a nullifier, a one-time value derived from a secret of the sender's and the block number, which stops the same balance being spent twice.

It also carries an encrypted message for every participant in the transaction, which tells the receiver what it received.

A transfer, step by step

Bank A sends 100 tokens to a client of Bank B:

  1. Request. On Bank A's chain, the client calls crossTransfer on the Enygma token (see RaylsEnygmaHandler). Bank A's chain first checks that the token is active and isn't frozen for Bank A or Bank B. The token then burns the 100 on Bank A's chain and records a transfer request. One call can pay up to five destination chains.
  2. Batch. Bank A's private relayer collects pending requests into a batch, up to 1,000 messages by default, so one Hub transaction can carry many client payments. This is the "double batching" of the Rayls research (ePrint 2025/1639): one transaction can pay several banks, and each payment can aggregate many client transfers. It picks the anonymity set: Bank A, Bank B and, if the network is larger, random other participants up to k.
  3. Prove. The relayer gets the shared secrets and tags from Bank A's key service, then asks the proofs API for a proof, using the last finalised balances on the Hub.
  4. Settle on the Hub. The relayer submits the proof and the encrypted messages to the token's Enygma contract on the Hub (transferBatch). The contract checks that the nullifier is unused and that the block number is valid, then verifies the proof. It records the transaction as pending and emits the encrypted messages.
  5. Receive. Every participant's relayer watches the Hub. Bank B's relayer finds the message with its tag, decrypts it and mints 100 tokens to the client on Bank B's chain. If the sender attached program steps, they run straight after the mint. The other participants in the set only update their stored random values.
  6. Finalise. A pending transaction becomes final when the Hub accepts a later Enygma transaction for the same token. After each transfer, the sender's relayer sends a zero-value validation transaction for this purpose. It finalises the previous transaction and adds cover traffic.

Rules and limits

  • One Enygma transaction per sender per block. The nullifier is derived from the sender's secret and the block number, so the relayer batches everything a participant sends in a block into one transaction.
  • At most k − 1 receivers per Hub transaction. If a batch pays more destination chains than that, the relayer splits it into several Hub transactions.
  • No transfers to the same chain. crossTransfer to the sender's own chain reverts. Payments between clients of the same institution are ordinary ERC-20 transfers on its chain.
  • Failures are reversed, not rolled back. The Hub transaction and the mint on the destination chain are separate transactions. If the mint fails on the destination, the relayers run compensating transactions that return the tokens to the sender's chain. It is not one atomic transaction across chains.
  • Frozen tokens stop. If the Private Network operator, or a compliance officer it appoints, freezes a token for a participant, the Hub broadcasts the freeze to every chain, and the sending chain refuses that participant's Enygma transfers and DvP operations for the token.
  • Mints and burns are public. When the issuer mints or burns on its chain, its relayer updates the token's supply on the Hub with the amount in clear. No proof is needed, because the issuer is authorised to change supply.

Programmable transfers

A transfer can carry program steps: calls to contracts on the destination chain, each given as a resource ID or a contract address, a function selector and arguments. On arrival, the destination chain's programmability executor runs the mint and then each step, all in one transaction: if any step fails, the mint fails with it, and the relayer reverses the transfer.

Each step's contract code and function must match an approved template in the Private Network's template registry, which the Hub replicates to every chain. A sender can only trigger calls the network has approved.

Program steps apply to Enygma transfers. Programmable DvP is not available.

Where to go next


Did this page help you?