Signature & Message Restrictions

Improved Signature Verification for Tetra Chain

With the emergence of multiple TON-compatible app chains, users can reuse the same keys and deploy identical contracts across different chains. While convenient, this introduces replay attack risks, where a valid signature from one network may be reused on another.

To mitigate this, a network-aware signature verification mechanism is introduced. Signatures become network-specific by incorporating a unique network identifier (global_id) into the signed payload. As a result, the same key and contract can be safely reused across different app-specific chains without signature collisions.


Design Overview

Most TON smart contracts verify external message signatures using the opcodes:

  • CHKSIGNU

  • CHKSIGNS

To minimize contract-level changes, the proposal introduces extended behavior for these opcodes, enabled via a VM capability. This behavior modifies signature verification by automatically including a signature domain derived from the network’s global_id.

⚠️ This mechanism is currently implemented only on the app-specific chain side and requires reserving additional VM opcodes for explicit signature domain handling.


VM State Changes

The TVM execution state is extended with an additional signature domain stack.

  • The top item of this stack is called the current signature domain

  • It acts as a modifier for signature verification opcodes (CHKSIGNU, CHKSIGNS)

  • For app-specific chains, the signature domain is implicitly pushed before contract execution

  • For mainnet, execution starts with an empty stack

An empty stack is equivalent to having signature_domain.empty as the current domain.


Signature Domain TL Scheme


Modified Opcodes

CHKSIGNU (f910) and CHKSIGNS (f911)

When the SignatureDomain capability is enabled:

  • The data being verified is prefixed with bytes derived from the current signature domain

  • For signature_domain.l2, the prefix is:

    • sha256(TL(signature_domain.l2, global_id))32 bytes

  • For signature_domain.empty, the prefix is empty → verification is fully backward-compatible with the original implementation


Example: CHKSIGNU


Example: CHKSIGNS


New Opcodes

The following opcodes are introduced for explicit signature domain management:

  • SIGNDOMAIN (f91800) Pushes the current signature domain Stack effect: - x | ⊥

  • SIGNDOMAIN_POP (f91801) Same as SIGNDOMAIN, but removes it from the stack Stack effect: - x | ⊥

  • SIGNDOMAIN_PUSH (f91802) Pushes a new signature domain (global_id or ) Stack effect: x | ⊥ - Constraint: -2³¹ ≤ x < 2³¹


Wallets & SDKs

  • Must operate with a known global_id of the selected L2 network

  • Must include this context when forming signatures

Last updated