SkyhookIdeas: Future Directions

Ticket Authentication

Design direction, not funded

Ticket authentication is the part of the proposed bidirectional MAST engine that decides who may claim an escrow. Satisfying a lock’s constraints proves that a qualifying Zcash action exists, but anyone can point at a mined action and recite its fields. Tickets close that gap: the lock’s creator signs a constant committed in the leaf, and a valid claim must present that signature, with part of it embedded in the payment’s encrypted memo. Verification is a single ecrecover against the key committed in the leaf and involves no decryption at all.

Roles and key custody

Three roles are involved, and none of them merges into another. The lock creator generates a script keypair before creating the lock, commits the public key in the leaf, and alone holds the private key for the life of the arrangement. The claimant builds the qualifying Zcash action and pursues the escrow. The relayer carries completed claims to the chain and holds nothing beyond what that transport requires.

Custody is deliberately concentrated in one private key per ticket family, which never appears on-chain. If it is lost, the ability to authorize claims is lost with it, by design; if it is compromised, whoever holds the copy can mint tickets. The damage is therefore bounded by key hygiene rather than by protocol logic, and custody guidance belongs in deployment documentation, where it can change without contract changes.

Minting

The creator mints a ticket by signing the leaf’s constant with the script private key. This is an ordinary ECDSA signature over an ordinary message, producing an ordinary triple (v, r, s), with fresh randomness for every ticket. Reusing randomness wouldn’t affect consensus, but it would link tickets cryptographically and invite the well-known key recovery from nonce reuse, so the minting tool draws new randomness for each triple, and its tests reject reuse.

A minted ticket names no claimant and refers to no action; those bindings come later, through carriage and submission. A creator can therefore prepare a whole family of tickets before any payer appears, which suits arrangements negotiated in advance.

Carriage

The claimant places the ticket’s v and r bytes in the plaintext of the action’s memo when building the transaction, in a reserved region at the start of the memo, followed by any application content, so ticket bytes never collide with user messages. A start index supplied by the claimant locates the region and is range-checked against the 512-byte memo, in the same way root offsets are checked against shorter buffers. The layout rule is fixed by the design rather than negotiated per claim, so all implementations agree without coordination.

The memo travels encrypted inside the note like any other, and the chain commits to its ciphertext through the standard memos digest. Verification consumes the committed bytes exactly as stored: it never decrypts anything, and no key material other than the script public key enters the check. This keeps verification down to hashing and signature recovery, which every implementation performs on the same byte path, leaving no room for divergences that could silently fork consensus.

The recovery check

The contract runs ecrecover over the leaf’s constant, using v and r from the memo and s from the claim. The check passes only if the result equals the leaf’s script key; any other output fails it, including the zero address the precompile returns for malformed input. A failure reverts the whole claim, leaving escrow, nullifiers and ticket records untouched.

Where each input comes from matters as much as the cryptography. The v and r bytes come from the committed memo region, never from detached inputs that an observer could swap out; s arrives with the claim, since no copy exists on-chain before submission; and the constant comes from the revealed leaf, not from the claimant. Each input therefore originates with the party that couldn’t profit from falsifying it.

Opaque treatment of v and s

The recovery identifier v is treated as pseudorandom output over the committed bytes and checked only for range: 27 and 28 are accepted and everything else rejected. The same applies to s, which is not normalized to the “low-s” form. Honest signatures are already pseudorandom, so canonicalization would add checks without adding security, while rejecting about half of all legitimate triples.

This deliberately departs from wallet conventions, which normalize aggressively to serve replaceability and mempool hygiene when many parties submit competing transactions. A ticket check has a narrower task, one check on committed bytes against a fixed key, and the byte form is already pinned by the commitment. How this neutralizes signature malleability is covered in the security analysis.

Binding the claimant

The recovery check authenticates the ticket, not the person submitting it: the triple is a bearer credential, and whoever validly presents it with a qualifying action may claim. Resistance to theft therefore rests on three layers, each necessary and none sufficient alone: secrecy of the credential, which travels through memo carriage and private handoff rather than public channels; private relay, which keeps the submission out of the public mempool where it could be copied; and the nullifier set, which stops reuse against the same action once the first claim confirms. The tooling uses private relay by default, so the protection doesn’t depend on users knowing about the threat. The security analysis examines this in detail.

Single-use and multi-fill tickets

A per-leaf flag decides whether one ticket settles one claim or a family of claims. One-shot locks set the flag and record spent tickets keyed by s, so the first valid submission consumes the ticket for good. Multi-fill locks leave it clear and rely on per-action nullifier marking alone, so each qualifying payment settles independently under the same ticket. Because the flag lives in the leaf, each lock’s author chooses explicitly: a bounty for exactly one solver sets it, and a standing offer that pays per delivery clears it. The verification code is identical in both cases except for whether the spent-ticket record is written.

What payers must keep

A claimant needs two things from the moment the transaction is built: the encryption randomness with the full opening data, which every later verification and audit step relies on, and the ticket triple with its start index, which is needed to assemble the claim. Losing either after broadcast turns a routine claim into forensic reconstruction, so the fill tooling logs both automatically. The openings also let the payer prove to a relayer that it holds the ticket and that the action qualifies, without exposing the credential publicly. The handoff carries the action reference, the triple and the start index, everything the relayer needs and nothing more.

See also