TYPE 0x0005 · SIGNATURE FAMILY

KEY_REF_SIG

Signature verification using a key commitment referenced from a relay block. Enables cross-rung key sharing without duplicating pubkey commitments, saving ~30 bytes per reference.

Signature Non-Invertible
KEY_REF_SIG RELAY RESOLVE SIG VERIFY RELAY[idx] PUBKEY (in leaf) + SCHEME Key resolved from relay → verify signature
FieldData TypeSizeSideDescription
relay_index NUMERIC 4 B Conditions Index into the rung's relay array. Value must fit uint16_t (≤ 0xFFFF) and must appear in the rung's relay_refs.
block_index NUMERIC 4 B Conditions Index of the target block within the resolved relay. Value must fit uint16_t (≤ 0xFFFF).
signature SIGNATURE var Witness Signature over the sighash. Scheme is read from the resolved target relay block (Schnorr default if absent); Schnorr is 64-65 B, ECDSA 8-72 B, PQ schemes variable.

PubkeyCountForBlock = 0 for KEY_REF_SIG. No PUBKEY in conditions or witness — the key (and its SCHEME) is dereferenced from relays[relay_index].blocks[block_index], whose own Merkle leaf already binds it at MLSC-proof level.

Conditions side (committed in the rung leaf):

0x0005 0 2 NUMERIC · 4B NUMERIC · 4B = 14 bytes

Witness side (in input witness):

0x0005 0 1 SIGNATURE · 64-65B ≈ 70 bytes
Total (conditions + witness) ≈ 84 bytes

KEY_REF_SIG resolves its public key from a relay block rather than folding it into the rung's own Merkle leaf. PubkeyCountForBlock = 0 for KEY_REF_SIG; the key is bound at MLSC-proof level by the target relay block's own Merkle leaf. Each additional rung referencing the same relay key avoids duplicating the key (~33 B) in multiple rung leaves and avoids re-revealing it in the witness.

1. Read both conditions NUMERIC fields and decode them as little-endian 4-byte values relay_index and block_index. If either is absent or its decoded value exceeds 0xFFFF (uint16_t range) → ERROR
2. Require relay context to be available (ctx.relays and ctx.rung_relay_refs). If unavailable → ERROR
3. Validate relay_index appears in this rung's relay_refs. If it was not declared by the rung → ERROR
4. Bounds-check: relay_index < relays.size() and block_index < relay.blocks.size(). Out of range → ERROR
5. Resolve target_block = relays[relay_index].blocks[block_index] and read its PUBKEY field. If the target block has no PUBKEY → ERROR. (The target block's pubkey identity is already pinned by its own merkle_pub_key at MLSC-proof level — no leaf check is performed here.)
6. Read the optional SCHEME field from the target block. If absent, the scheme defaults to Schnorr.
7. Read this block's witness SIGNATURE. If missing → ERROR
8. Dispatch VerifySigWithScheme(target_pubkey, witness_sig, target_scheme, ...). Size checks for the resolved scheme apply here (Schnorr 64-65 B, ECDSA 8-72 B, PQ scheme-specific). Invalid → UNSATISFIED; valid → SATISFIED
ConditionResult
Either NUMERIC field absent, or value > 0xFFFF (uint16_t cap)ERROR
Relay context unavailable (no relays or rung_relay_refs)ERROR
relay_index not declared in this rung's relay_refsERROR
relay_index or block_index out of boundsERROR
Target relay block has no PUBKEY fieldERROR
Witness SIGNATURE missingERROR
Resolved-scheme size check fails (e.g. Schnorr sig not 64-65 B)UNSATISFIED
Signature verification failsUNSATISFIED
Signature valid against resolved target-block keySATISFIED
Conditions (committed in the rung leaf)
{
  "type": "KEY_REF_SIG",
  "inverted": false,
  "fields": [
    { "type": "NUMERIC", "hex": "00000000" },
    { "type": "NUMERIC", "hex": "00000000" }
  ]
}
Relay (referenced by relay_refs)
{
  "type": "SIG",
  "fields": [
    { "type": "PUBKEY", "hex": "02abc1...33 bytes" },
    { "type": "SCHEME", "hex": "01" }
  ]
}
Witness (input)
{
  "type": "KEY_REF_SIG",
  "inverted": false,
  "fields": [
    { "type": "SIGNATURE", "hex": "...64-65 bytes (Schnorr) or scheme-specific..." }
  ]
}
Multi-Path Key Sharing
A single key bound to a relay's Merkle leaf is referenced by multiple rungs via KEY_REF_SIG. For example, the same hot-wallet key can authorize both an immediate spend (rung 0) and a timelocked recovery (rung 1) without folding the key into each rung's leaf separately.
MLSC Witness Compression
In Merkelised Ladder Script trees with many spending paths, KEY_REF_SIG reduces the size of each rung by ~30 bytes. Since relays are revealed alongside the spending rung in the MLSC proof, the verifier always has access to the referenced key commitment.
Relay-Based Key Management
A relay defines the authorized signer (key folded into relay's Merkle leaf). Multiple rungs can reference the same relay via KEY_REF_SIG to enforce that the same key is used across different spending paths with different additional conditions (timelocks, hashlock, etc.).