All articles

One-Time Borrow Gets A Hash-Chain OTP Design

Late July produced one of the cleaner post-Toccata design threads in the channel: how to let someone borrow a UTXO once without turning that permission into a reusable hot key.

On July 30, Michael Sutton told Maxim he had found a way to provide an OTP for a borrow: a one-time allowance to borrow a UTXO, after which the next state recreates the permission model without leaving a standing secondary spend key. Maxim said the older nearby idea was covenant-lineage permissioning, which can cover one-time or longer-lived attempts. Sutton's requirement was stricter. The borrower should get only one use. [1] [2] [3]

Maxim sketched a covenant-id permission UTXO that can be spent only by recreating the owner UTXO and producing a single borrower-controlled result. Sutton called that too complicated and said it did not cleanly read as a pure one-time allowance. He said he had a simpler hash-only solution. [4] [5] [6] [7]

The hard part was replay. If the borrower reveals a preimage in the mempool, observers can see it. If the same commit remains valid, anyone can reuse it. If the borrower may choose the next commit freely, the borrower can also reuse the permission. Sutton's hint was to turn the reveal into a new commit. The scheme can support a finite number of borrows, then needs reset or reallocation, with N allowed to be large. [8] [9] [10] [11] [12]

Maxim eventually landed on the structure Sutton wanted: a hash chain. The simpler formulation was a chain of N hashes, hash(hash(...hash(seed))), starting from the top-level hash. Each successful borrow reveals another layer, and that revealed value becomes the next commit. Sutton confirmed the idea. [13] [14] [15] [16] [17] [18]

They also fixed the threat model in public. Maxim kept returning to the fact that a mempool observer can race the intended borrower. Sutton agreed that is possible and said it is not the threat model for the use case he cares about. The target flow is a wallet that wants to stay in control of its UTXOs, issue a one-time receive or borrow capability, wait for payment, and revoke if payment never arrives, without signing every receive path. In that setting, stealing the current OTP from the mempool does not create a long-lived attacker capability the way a standing secondary key would. [19] [20] [21] [22] [23] [24] [25] [26]

Sutton said the original inspiration came from an old paper and linked it after the riddle played out. The channel result is not a merged standard. It is a crisp pattern: finite hash-chain OTPs for one-shot borrow permissions, with explicit rejection of "standing borrower key" as the default answer. [27]


All sources link to public messages in the Kaspa Core R&D (public) Telegram channel.

Sources

  1. Kaspa Core R&D · message 15532
  2. Kaspa Core R&D · message 15534
  3. Kaspa Core R&D · message 15535
  4. Kaspa Core R&D · message 15538
  5. Kaspa Core R&D · message 15539
  6. Kaspa Core R&D · message 15540
  7. Kaspa Core R&D · message 15542
  8. Kaspa Core R&D · message 15548
  9. Kaspa Core R&D · message 15549
  10. Kaspa Core R&D · message 15551
  11. Kaspa Core R&D · message 15553
  12. Kaspa Core R&D · message 15554
  13. Kaspa Core R&D · message 15561
  14. Kaspa Core R&D · message 15562
  15. Kaspa Core R&D · message 15573
  16. Kaspa Core R&D · message 15574
  17. Kaspa Core R&D · message 15575
  18. Kaspa Core R&D · message 15576
  19. Kaspa Core R&D · message 15555
  20. Kaspa Core R&D · message 15556
  21. Kaspa Core R&D · message 15568
  22. Kaspa Core R&D · message 15569
  23. Kaspa Core R&D · message 15570
  24. Kaspa Core R&D · message 15571
  25. Kaspa Core R&D · message 15577
  26. Kaspa Core R&D · message 15578
  27. Kaspa Core R&D · message 15582

More Kaspa Articles

All articles