Request for SuApp: Kettle Cash

TEEs can easily provide a “one shot signature” or “anti-equivocation” feature. This is very powerful and underrated, even in the projects otherwise pushing the limits with TEEs. Let’s make some clear illustrative examples that use this to its fullest.

The basic appeal is this: We should be able to place deposits to a key controlled by a TEE - now, any transactions signed by that TEE can be considered gauranteed-finalizable because of the non-equivocation. The TEE would be ensuring the key is only used in a write-once way, so if you’re holding a signature from the TEE you know it can’t be contradicted by any other signature. Such signatures could be passed around like instant-finality certificates, including from one TEE to another.

The challenge is we’ll still have to deal with Availability. The singular TEE controlling the active key could crash. We could run a consensus protocol among the TEEs but that would undermine the benefits of instant-finality-from-Non-equivocation.

What we might try instead is something like a “federated” service. When your coins are deposited in a single Kettle, you will be subject to the risk of that Kettle becoming unavailable. However, the Kettle will be able to issue you a “claim check” which you can very easily deposit somewhere else. Here’s an illustration:

Here’s (a paper I like) from Sattath and Ben-David about constructing efficient e-cash using a “One Shot Signature.” They envision instantiating this using Quantum states, but we can just replace the word “quantum” everywhere with “TEE” instead and understand it as a suapp. Specifically section “8.1 Sending Quantum Money over a Classical Channel” gives an interesting story about using these one-shot signatures to make an e-check system.

[we show] a quantum money scheme that is derived from a tokenized (either private or public) signature scheme. In particular, we show how to convert a quantum bill into a classical “check”, which is addressed to a specific person and can be exchanged for a quantum bill at a bank branch. Recall … a testable public (private) digital signature scheme satisfies the definition of a public (resp. private) quantum money scheme, with the signing tokens acting as the quantum bills. Now, in this setting, if Alice holds a quantum bill, one thing she can do is spend it the usual way. However, an alternative thing she can do with the bill is use it to sign a message. Such a signature will necessarily consume the bill, and hence can be used as proof that Alice has burned her bill.

In particular, consider what happens if Alice signs the message, “I wish to give a bill to Bob”. Alice can send over this classical signature to Bob, who can verify the signature using the public verification scheme. Bob can then show this signature to his bank branch. Crucially, the bank knows that Alice burned her bill, since the signature is valid; hence the bank can safely issue Bob a bill. In essence, this
usage converts a quantum bill into a classical check!

I think the biggest remaining limitation of this proposal described her is the lack of recourse if a users’ preferred TEE crashes. It would be nice to have a backup option, if the quantum key gets stuck then the last holder can claim it on L1. I think this could be improved by adding a “Recovery key” and an associated timeout, but this got confusing to think about.

The main related work for using write-once payments using TEEs and blockchains is TEEChan and TEEChain / (github). Although these are defined in terms of channels, they seem to function a lot like the checks described here. They put some work into mitigating TEE compromise, whereas that’s explicitly left out of scope here.

5 Likes

:person_raising_hand:

…wait for the TEEception paper — or; ‘Yo dawg, I heard you like TEEs, so we put a TEE in your TEE so you can TEE while you TEE’

1 Like

Here’s a first attempt at implementing this in Sirrah:

A check has a very simple structure, it names a user account that’s the recipient of the check, and it names a Kettle where it can be deposited:

struct Check {
    uint amount;
    address recipient; // User account of recipient
    address kettle;    // Recipient's Kettle
    bytes32 nonce;     // Unique tag
    bytes att;         // Signed by issuer
}

There are two ways to issue a check. One is by an onchain deposit, which produces a check with an empty attestation, but stores the check in an on-chain mapping.

function onchain_Deposit(address kettle) public payable 
   returns(Check memory c) {
    ...
	deposits[CheckSerial(c)] = true;
    ...
}

The second is with an off-chain Kettle query, which produces a check and attests to it using the Sirrah key manager, updating a volatile record of the user’s balance.

function offchain_IssueCheck(address recipient, address kettle, uint amount) public 
   returns (Check memory) {
    ...
    c.att = keymgr.attest(CheckSerial(c));
    ... 
    _WriteBalance(msg.sender, balance - amount);
    ...
}

To deposit a check, invoke an off-chain Kettle query, which verifies the check, then atomically marks the check as spent and updates the balance.

function offchain_DepositCheck(Check memory check) public {
    ...
    Suave.volatileSet(CheckSerial(check), 
                     bytes32("voidvoidvoidvoidvoidvoidvoidvoid"));
    _WriteBalance(check.recipient, balance + check.amount);
    ...
}

You can issue and deposit as many offchain checks as you want, hopping from Kettle to Kettle in a single message, without any interaction on-chain.

So far, the limitation remains that there’s no protection against a Kettle crashing…

2 Likes

Hello all!

I do not know if you are aware, but we’re researching ‘quantum’ quantum 1-shot signatures:

…Rather ironically, this stems from a workshop that we co-hosted together last year. I thought I can provide some useful context here: Implementing 1-shot signatures is:

  • Proved to be classically impossible if you do not have any form of shared state;
  • Easily classically implementable otherwise.

In the latter case, the standard example I can think of is: A smart contract on a blockchain that:

  • Flips a bit b from 0 to 1 when a given function f gets called
  • Returns error if f is called and the b is 1
  • Does not provide any mechanism to flip b to 0.

This easily allows any user to sign a message just once by calling f. Obviously this signature scheme is as secure as the chain not rolling back/being reorged.

This said, what you suggest works for sure but the whole security hinges on this:

The TEE would be ensuring the key is only used in a write-once way, so if you’re holding a signature from the TEE you know it can’t be contradicted by any other signature.

Essentially you need to ensure that there’s at least 1 bit living on the TEE that, once flipped, never flips back. This information cannot be saved on any piece of external state - encrypted or not - that can be copied, unless it is also uniquely linked to something that lives forever on the TEE and cannot be rewritten ever (the bit above).

By the way, we are working on a Q1S design which:

  1. Requires way less quantum computational resources than the original Amos, Georgiou, Kiayias, Zhandry paper;
  2. Implements semi-quantum tokens, which still require the presence of a trusted ‘bank’;
  3. Slaps the bank on a TEE to minimize trust.

This is still not public yet, but we believe it is a nice way to ‘use TEEs, but as little as possible’. What I mean by this is that all the info that needs to run on the TEE is

  • Fully classical
  • Fully ephemeral

And that we use quantum stuff just enough™ to ensure the collapse of a quantum state, and hence the impossibility of reusing the signature twice. With this approach, the ultimate trust assumption on TEEs can be phased out in the future (for now this is kinda possible by assuming iO, which sucks, but never say never!).

In any case, the whole team working on this will be at ETHcc if you want to discuss further. We’d be happy to :smiley:

2 Likes

Ah interesting. From what you are saying it seems that answer to Andrew’s question of persisting through a crash/restart:

Is simply no - you can’t protect against a crash in this scheme.

I could see an open hardware initiative to build a TEE chip that includes a single quantum bit.
How realistic is the expectation you will have computing resources with access to quantum states that live for long enough for this whole thing to be feasible? It’s not like those live on hard drives right

Wait wait wait lol.

I am not necessarily saying this. What I am saying is that quantum one shot signatures work because of the quantum no-cloning theorem, which doesn’t allow to copy quantum resources. Since you cannot copy the quantum state, and since this state is prepared by random sampling, it is essentially unique. To use it, you need to measure it, and as you do the state collapses. This allows you to effectively implement a ‘use once’ mechanism.

In the classical case, we do not have no cloning: Classical resources can be copied ad libitum. Clearly if I have a ‘state’ on an encrypted file to feed my TEE I can copy the file, feed it to the TEEs multiple times, and sign multiple times. This was precisely the initial problem blockchains solved: We needed consensus protocols to ensure the absence of double spending, by implementing a common ledger that couldn’t be modified by any single actor or malicious clique.

So I am not saying that implementing the TEE case results in the system being unrecoverable after a crash. I am saying that there MUST be some piece of information that

  • Lives on the TEE
  • Stays there forever
  • Can only be modified in one direction, e.g. flipping a bit 0 \mapsto 1 but not 1 \mapsto 0.

Notice that in this particular case the cryptographic properties of a TEE are barely needed by the way.

I see no need for it. As I said in my post,

So you do not need to implement any quantum resource on any TEE whatsoever. What’s available now is more than enough.

2 Likes

Regarding this point, I am wondering if the combination of sealing + hardware-backed monotonic counters (like the one from SGX) wouldbe beneficial here.

  • One could for example, persistently seal the key and the current counter value.
  • upon signing, unseal, increment monotonic counter and discard key from memory (because it is not needed anymore and to avoid potential leakage).
  • extra: can be combined with other counters and using trusted timestamps to support TTL keys/signatures if necessary.

This is just a naive approach as it doesn’t protect against side-channels, but it can still be hardened against them (e.g. multi-party protocols)

This is ofc assuming the secure hardware-based monotonic counter is trusted and enough for our use-case.
Potential issues:

  • it is finite. However, probably solvable by using a combination of several counters.
  • hardware failure. This would require to implement a protocol to recover the correct latest state

It is not perfect approach but what is the general opinion about it?

Probably a simpler approach - if possible - is computing an ephemeral keypair on the TEE, communicate the public key, use the private key to sign only once and then destroy the internal state.

To do this tho one must ensure deletion and that the pseudorandom mechanism for keypair generation (and it’s entropy) does not leak.

For the layman, this is the equivalent of:

  • Instantiate a hardware wallet
  • Do not write down the seed phrase anywhere
  • Use it to sign precisely one transaction
  • Reset the hardware wallet.

Basically to do this you do not need the full power of TEEs, but just one modified Ledger Nano S :slight_smile:

Non-volatile hardware-backed counters would be a great way of handling crashes. In SGX, not only was the non-volatile counter slow, but it had such a short lifetime it could be burned out. The best reference by far is the ROTE paper:

To summarize, we found out that counter updates take 80-250 ms and reads 60-140 ms. The non-volatile memory used to implement the counter wears out after approximately one million writes, making the counter functionality unusable after a couple of days of continuous use. Thus, SGX counters are unsuitable for systems where state updates are frequent and continuous.

The ROTE paper of course also proposes instantiating a non-volatile counter service from of a distributed network of redundant volatile counters. This is closest to what we do in Sirrah for the auction example, where the on-chain is used as the source of truth for sequencing all commands.

The Kettle Cash proposal is the extreme, presented as the optimistic best-performance baseline, that only uses a volatile monotonic counter implemented using Suave.volatileGet/Set` on one machine at a time. You wouldn’t use this for buying coffee, and I think to go further it will take a specific application. I think this would be relevant for high frequency settling when you’re already OK gambling on the uptime of a particular machine.

Also if we had a really fast and virtualizable non-volatile hardware counter, even if it were provided as an external module, that could do the trick. My favorite papers on this is TrInc which proposes a dedicated module for a “Trusted Incrementer” and how you can build distributed systems on it. This is a good application goal for the OpenTEE stuff :]