A relayer cannot steal money, as the Tornado smart contract will not allow this. Here is what Tornado FAQ say:
Relayers are used to withdraw to an account with no ETH balance. The relayer sends a withdrawal transaction and takes a part of the deposit as compensation (the protocol itself does not collect any fees). The relayer cannot change any withdrawal data including recipient address. The Tornado Cash initial developers do not control or play any role in relaying transactions, the relay network is independent and run by community.
So a relayer just publish other people's transactions, pay for gas, and receives a small fee forthis, but he cannot modify the transactions, thus cannot reroute the funds.
A Tornado withdrawal transaction consists of the following parts:
- a zero-knowledge proof of transaction validity
- the root of the Merkle tree where the deposit to be withdrawn is registered
- the nullifier hash of the deposit
- the recipient address funds are to be sent to
- the relayer address fee is to be sent to
- the fee amount
- the amount of ether to be sent to the recpipient by the relayer as a partial fee refund (needed when ERC20 tokens are withdrawn, so the repicient could use this ether to pay for gas when moveing the tokens further)
The zero knowledge proof guarantees that the deposit with given nullifier and amount actually exists in the Merkle tree with given root, and that the one who generated the proof knew the secret deposit key and agreed with all the transaction parameters.
Relayers are needed, because in case a user would pay for the gas by himself, the origins of the ether used to pay for the gas might be traced thus deanonymizing the user.