Spark Program | CKB Revocable Timelock (CRT) — Timelock Encryption You Can Cancel

Reply to Spark Committee — second Pending

Thank you xingtian, and thanks to the committee for a genuinely careful second read. I want to answer the three points properly, and then make a proposal about what happens to this application.

Before the details, one thing I should have caught myself: two of the three concerns are answered by mechanisms that exist in the design and that I placed out of scope in the proposal. Proof-of-possession answers point 2. Mandatory-node access trees answer point 1. Both are in SPEC.md and both are in my “deliberately not promised” list. So the committee reviewed a version of CRT with its two load-bearing safeguards removed and correctly found it thin. That’s a scoping mistake on my part, not a disagreement.

1. Collusion

Correct, and I conceded it in my last reply: nothing prevents a threshold of operators who were malicious from the start from sharing keys privately. I’d add three things.

Public early release is detectable, contrary to the note. The release condition is consensus chain time. A release value published before deadline + grace is evidence anyone can verify against the chain and submit, and it is slashable in the full design. What is undetectable is private collusion — operators exchanging keys without publishing. I want to keep those two separate rather than claim detection I can’t deliver.

This is true of every threshold timelock, drand included. drand’s federation could collude and produce a future round’s signature early; nothing structurally prevents it. I’m not offering that as an excuse, only as a calibration: this isn’t a defect CRT introduces, it’s the standing cost of not having the user hold the key.

The mandatory-node path removes it entirely for the operators the user doesn’t control. The access tree composes an XOR branch with the threshold branch. The user places their own node in the XOR branch, and the secret then requires that node’s key plus a threshold of the rest. Every other operator can collude, and they reconstruct nothing. To be precise about what this does and does not give you: it does not make rogue nodes delete anything. It makes their retention worthless, because their shares don’t reconstruct without the branch the user controls. That is the answer for data that warrants it, and it should have been in scope.

2. Data availability

This is the strongest of the three and I don’t want to wave it away with “enough nodes and good statistics.”

The design’s answer is proof of possession. At intervals, a node must sign a chain-derived challenge — blake2b256("CRT/v1/pop" || T || block_hash(H)) — with the per-switch key, and its fee claim is gated on that signature. Because the challenge derives from a block hash, it can’t be precomputed. A node that quietly dropped its key fails its next PoP, and it fails it while the stake is still bonded and the user can still rewrap, rather than at the deadline when it’s too late. Combined with the headroom figures the coordinator publishes, “claimed to store it and vanished” is a condition that surfaces months early, not at release.

Where the committee is right: PoP is in my out-of-scope list, so as proposed there is no availability guarantee at all. That was wrong. PoP is the mechanism that makes a threshold scheme honest, and it belongs in v0.1.

On “worse than a simple time lock” — I’d push back gently. A simple timelock has an availability assumption too; it’s just hidden in a federation you don’t choose and can’t audit. CRT’s version is explicit, measurable, and the user can buy headroom by widening the set. That’s a real difference, but only if PoP ships.

3. Whether splitting helps at all

Here I think there’s a mismatch in what’s being compared, and I’d like to set it out rather than concede it.

The note compares CRT against a single key under the user’s control. That isn’t the alternative — it’s a different product. If a key exists that the user can use to decrypt, then:

  • a dead man’s switch cannot work, because the user is by definition gone at the moment of release;
  • a sealed-bid auction is not sealed, because the auctioneer can read bids before the reveal;
  • VoteSecure’s tallies are readable by the operator mid-vote, which is exactly the property the scheme exists to prevent.

A timelock’s defining property is that nobody, the creator included, can decrypt before the condition holds. The moment one party can, it’s encryption with a promise, not a timelock. So the honest comparison isn’t CRT versus a user-held key, it’s CRT versus drand: a fixed federation the user cannot choose, cannot extend, cannot add their own node to, and cannot cancel.

On the specific scenario raised — the user’s own node compromised while others release their shares — the mandatory branch makes the user’s node necessary, not sufficient. Compromising it yields nothing on its own; an attacker still needs a threshold of the rest. And the standing trade is one I state plainly in the spec: every mandatory node makes the secret harder to steal and easier to lose, one for one. Users choose where on that line they sit. A fixed federation doesn’t offer the choice.

What I’d like to do with this application

I’ve been working on something broader in parallel: a revenue layer for CKB nodes, where nodes opt into running code embedded in cells and collect application fees for it — a generic service runtime rather than one hardcoded use case. I’ve posted it here: https://talk.nervos.org/t/a-revenue-layer-for-ckb-nodes

CRT is the first service I’d deploy on it, but it isn’t the point of it. And it changes CRT’s economics substantially: with that layer in place, the node software, the operator set and the fee mechanism stop being things I have to build and fund, and CRT becomes a cell-resident service I can develop incrementally as a solo developer.

So rather than have the committee spend a third round on this, I’d like to withdraw the CRT application for now. Not because the concerns are unanswerable — I hope the above shows they’re addressable — but because the right version of CRT now looks like a service on a runtime that doesn’t exist yet, and asking for three months of funding to build the wrong layer would waste your time and mine.

I’ll resubmit if and when the runtime work justifies it, with PoP and mandatory-node trees in scope from the start rather than deferred.

Thank you for the time the committee has put into this. The second review was more useful than the first, and the pressure on the security model is what pushed me to look at the layer underneath it. I’d genuinely welcome the same scrutiny on the revenue-layer thread if any of you have the appetite.

Patrick

2 Likes