[idea] Flexible Phonons

About a month ago, @AndrewB , @rake, @hinchy and I considered the requirements for ECASH. Among them, change without access to the internet stood out as core need for ECASH. Something we cannot do today.

@hinchy and I would like to present to you Flexible Phonons:

The purpose of Flexible Phonons is to make it possible for two parties to settle transactions without the internet, using assets both parties trust, and not relying on a 3rd party to issue change.

Though the inspiration for this construct was ECASH, we believe Flexible Phonons can open up a world of possibilities for the protocol:

  • Gaming: Debiting hit points, armor damage, mana or experience for characters/equipment/stuff in games.
  • Punch Cards: debit coffees, train or bus rides, anything today that has a “loadable card” mechanic
  • Cash: Enabling offline exchange for any currency/medium perceived as backed by a trusted party (governments, banks, credit unions)

Flexible Phonons are designed to use most existing applet functionality. We want them to behave much like any other standard phonon when possible.

How are they different from a standard phonon?

  • They are attested by the issuer/authority on creation. I call this feature “branding” (like branding a cow) because they are marked by their creators upon creation with a stamp that cannot be faked or changed. Read more about Branded Phonons here.
  • Their value is not fixed (like a backed phonon whose asset immutably awaits on chain) but can increment and decrement
  • After being instantiated at creation by the issuer, the value cannot be edited by a user. Instead, the phonon’s value can only be updated by the card itself when making payments.

We have prototyped the design, and have workable code for the ‘repl’. You can play with the code yourself with this PR.

See the Technical Change Summaries in the links above to see what may need to be adjusted in the client and applet to support this implementation.

Also, I’ve submitted this for @deviator and @nate to review, but they’ve been super duper busy getting testnet going (yay) so let’s not bombard them with questions now for a few more weeks :slight_smile:

Excited for the discussion!


The requirement
A requirement from the ECash Bill reads

(7) capable of instantaneous, final, direct, peer-to-peer, offline transactions using secured hardware devices that do not involve or require subsequent or final settlement on or via a common or distributed ledger, or any other additional approval or validation by the United States Government or any other third party payments processing intermediary.

The situation
A shopper has a single phonon representing $5 and wants to buy a $2 item from the store. The store after a busy day only has a single $5 phonon.

With Current Phonon Protocol Features
The store is unable to meet the change requirements. In this situation, the shopper or store would need to use a change making service which breaks the requirement of “direct, peer-to-peer, offline”. One solution to this would be to only issue phonons in the lowest denomination but then we run into card memory limitations when carrying any meaningful value.

With Flexible Phonons
The shopper’s card creates a new phonon, assigns $2 value to it and reduces the value of their $5 phonon to $3. The shopper then sends the new $2 phonon to the store’s card. The store’s card increases their $5 phonon to $7 and deletes the received phonon.

I think of Flexible Phonons as balances on cards that are updated by sending and receiving phonons. It is basically the ERC20 of the Phonon Protocol. I am very excited for this.

1 Like

Below is a condensed/edited version of a discussion I had with Cloak in the discord.

Where is the attesting happening exactly?
A flexible phonon is an extension of a branded phonon. A branded phonon is created by supplying a private key to the applet. The applet derives the public key from the private key and adds it to the phonon’s metadata. Only the applet is able to set this this property so it is guaranteed that only the holder of the private key is able to create phonons with that “brand”. Very similar to how only the owner of the USDC ERC20 contract is able to mint USDC. Phonons with the same brand can be thought of as fungible. Flexible phonons take this a step further and allow phonons with the same brand to be combined and divided. You receive a flexible phonon as you do any other. The only difference is, if you already have a flexible phonon with the same brand on your card, when you receive another the two phonons will be “combined”.

1 Like

This is super cool. I don’t quite get the increment/decrement aspect. Is this trust based from a centralized party?

Hey @mickey , I’m confused by your question.

Short answer: No.

Long answer: see below

First, let’s revisit how Standard Phonons work today:

  • Value and CurrencyType are attributes of a phonon (example: 5 Ethereum)
  • These attributes can be set/updated/changed by anyone who has the phonon in their possession (can change from 5 to 3, or Ethereum to Bitcoin). It’s not common for someone to want/need to change these descriptor attributes, but they can.
  • For a phonon whose Value is 5 and CurrencyType is Ethereum, does it actually have 5 ETH in it? Maybe, maybe not. Depends if the person has loaded it with 5 ETH (on the blockchain). But because it is described as having 5 Ethereum, you expect it to contain 5 ETH, and would validate accordingly (if you had access to the internet)

Flexible Phonons are similar, but with a few adjustments:

  • Value and CurrencyType are also attributes of a flexible phonon. However:
    • CurrencyType will always be equal to Flexible.
    • Value and CurrencyType can only be set when the phonon is created (very unlike a standard phonon). The applet disables the setDescriptor method to work for Flexible phonons. Nobody can adjust these meta data directly after it is created.
  • How does increment/decrement work?
    • Because the applet disables the setDescriptor method on the card for CurrencyTypes = Flexible, It is impossible for Value to be changed directly for flexible phonons.
    • Instead, a new method in the applet handles the transfer of value between Flexible Phonons (you can see how this works in the code we’ve whipped up).
      • Let’s say you have a Flexible Phonon with value 4. And you want to send me 2 value. Here’s what happens:
      • The card will 1) create a new phonon on the fly (with Value 0, CurrencyType Flexible), 2) subtract 2 from your phonon 3) add 2 to the one it created 4) send the other person the newly created phonon.
      • It is impossible for the double spend to happen (i.e. subtract 0, add 2) because this math is accomplished for both phonons inside the same method at the same time. The applet cannot add to a flexible phonon what it has not yet taken away from another.


Because all of the above is controlled by the card, there is only 1 thing you need to know/trust for Flexible Phonons. And that is the meaning of the public key which is tagged to the Flexible Phonon when it is created. (Reminder, this public key is deduced by the card from the private key the creator gives when creating the phonon.

  • Example: the United States government may use 5 different private keys when creating Flexible Phonons that contain “pennies”. And they may create a million Flexible Phonons with those keys that each contain $5 worth (5000 pennies). This means, anytime you encounter one of those Flexible Phonons (which you identify since they are tagged with the public key for 1 of those 5 private keys used by the US Gov to mint pennies), you can be certain it contains pennies.
  • All you need to “know” to check/verify the authenticity of a Flexible Phonon is the public key used by the guarantor. This can be stored easily in your client. We could explore storing an array of some on the card, but probably not necessary.

Interesting idea, reminds me of the design for fractionalized phonons we discussed a while back.

I see a couple ideas combined here actually, there’s a phonon transfer design that uses an account model instead of the current UTXO model. This has the great benefit of not requiring fixed denominations, and saves on storage, since an entire asset can be represented within a single Phonon. The cost of course is a good deal more complexity in the card implementation for Phonon transfers.

The other idea is the “branded” phonons thing, which is an interesting way to validate provenance of an asset I guess.

The branded idea is interesting but I’m not sure how secure the proposed implementation is. My main objection is storing a user generated private key inside a phonon, whereas all phonon private keys within “normal” phonons are generated on card.

It scares me to allow the user to add a private key that was not generated on card, as it opens up new attack vectors whereby a private key that has been duplicated outside of phonon is then inserted into a phonon card and passed off as a genuine phonon key.

I realize the applet logic is supposed to prevent this by locking the descriptor for these assets, but in practice the risks of adding this complexity will bleed over into the existing implementation. Any mistake in this implementation could also blow a hole in the normal Phonon security model.

Also, I don’t think that implementation of branding is optimal for the attestor or the attestee. If the attestor copies their private key into a phonon to prove the origin of an asset, any subsequent leak of that private key invalidates every asset that has ever been “branded” by that key.

Actually I think the card already has an implementation of this that can be adapted for this purpose, and that’s the signature scheme used in Native Phonons. Essentially, the mining card issues a signature using it’s identity private key, which is then trusted by recipients by checking the certificate chain for the CA which the card already trusts.

I propose then, for a “branded” Phonon, the data that should be passed from the issuer is the following:

  1. A Certificate Authority Public Key (This Certificate represents the trusted identity of the issuer)
  2. A unique identifier for the account (likely a hash)
  3. The value of the account at initial creation
  4. A signature from the CA private key over the unique identifier and value

Now, when two users with assets from this issuer want to transfer them, the counterparties can check each other’s asset’s signatures against the public key they each have in their own certificate. This will also allow them to match up the asset type and increment/decrement the correct balance during their transfers.

The advantage of using hash + signature + cert instead of directly using the private key is that you never have to copy a private key from outside of the Phonon Protocol into the applet, preserving that fundamental property of the security model. I think it also solves some issues in how cards trust each other’s transfers and establish an initial balance but I haven’t thought that all the way through.

Anyway, overall I like the idea, I think it’s super powerful and we should keep it in mind for the future. At the moment I think it requires a lot of additional complexity in the card applet logic especially. Not only is there a new flow for deposit and redeem on this assets, they would require large changes to core card commands like SEND_PHONONS and RECV_PHONONS to handle the account model increment/decrement logic and alternate asset validation. For now I’d prefer to keep the implementation focused on normal Phonons for Beta, as there is already a long way to go on the roadmap to get blockchain backed phonon transfers working securely and smoothly, but I think this is worth revisiting as the basic implementation stabilizes.

1 Like

@Senor might think differently but in my mind the private key would never be saved to a phonon or anywhere in the card. Instead the applet would use the private key to derive a public key which is added to a phonon property that can only be written to by the applet. The private key would then be removed from the applet. I don’t know the ins and outs of Javacard so this flow is possibly very insecure but wanted to clarify that the private key isn’t saved to a phonon.

Regardless if the private key is copied to the phonon or not, I 100% agree that the private key used to create a “brand” needs to be kept secure for this reason.

Does this mean a card would need to “know” of a brand before it can receive it?

1 Like

Thank you @deviator for your thoughtful response. A couple of clarifications, agreements and requests below:

Clarification: My implementation does not store the branding private key on the phonon, nor does it replace or swap out the genuine phonon key. This would break the intrinsic security rules that we trust about phonons.

What I’m doing is leveraging the TLV structure. I created a tag TagCreatorPublicKeyTLV, and fill it by taking a private key passed by the creator (the creator manages the security of that key on their own offline) and deducing its public key, when the Flexible Phonon is created. I make it impossible for people to fake a flexible phonon by simply tagging a known public key to a phonon by controlling how flexible phonons are created - primarily by using CurrencyType as a control.

What I like about my implementation approach - is it completely preserves and uses the existing phonon structure and security model, and core functions like send and receive.

I expect the deduction of the public key of the branding private key to happen on the applet itself:

privateKeyParsed, err := ethcrypto.HexToECDSA(privKey)
publicKeyBytes := ethcrypto.FromECDSAPub(&privateKeyParsed.PublicKey)
TagCreatorPublicKeyTLV, err := tlv.NewTLV(TagCreatorPublicKey, publicKeyBytes)

I agree that should the branding private key ever be compromised, that would nullify all phonons tagged from that private key, which would not be great. Creators would need to secure their private keys properly. Maybe this is too difficult at a scale for a customer like the United States government.

Agreement: I am open to any alternative designs that achieve the same outcomes. My goal is to make us eligible for things like ECASH, and am open to anything that gets us there.

Agreement: We should definitely stabilize the existing functionality before proceeding.

Request: Do we have a functionality backlog? Or does our roadmap represent our backlog? I think we are in agreement that the power of this functionality (however it is designed) is immense and worth prioritizing and keeping front of mind. I know @AndrewB wants to see ECASH be within our reach.

1 Like

I think the easiest way to handle offline verification of values is as follows: at some point after the phonon has been created, the phonon creator can submit their descriptor and pubkey to a trusted 3rd party phonon validator, who checks the chain to verify the amount of currency that is being claimed actually is in the wallet associated with the phonon. At that point, the 3rd party generates a certificate to then be added to the phonon descriptor. Since the cards cannot sign data, as long as the trused 3rd party isn’t lying, the phonons will always have at least the value indicated on the certificate.

The proposed phonon transfer flow will allow the receiving client to inspect the descriptor and pubkey before phonons are sent. That inspection period is where the client can inspect the signature of the proposed phonon

Users will be able to configure the trusted 3rd parties they trust, and which ones they will revert to checking the validity of on their own.

As for issuing change via phonon, without interacting with a 3rd party, I’m not sure if this is something we should be trying to do.


Thanks @npmaile-old .

I’m totally down with your and deviator’s alternative design approaches to branding phonons; trusting a phonon came from a specific source is the need. You know better than me how to get there.

As far as this last point is concerned - it comes down to value and Phonon’s goals I guess.

I think there is a ton of value in designing a way for phonon to handle an account model in addition to our UTXO model. If we want to be eligible for ECASH, this would be dealbreaker I believe; P2P offline change making is a must. I like my ideas relating to gaming and punch cards, but admittedly you could call those shiny objects and drifting from our core value offering.

1 Like

I do like the idea of defining a currencyType that specifically works on an account model rather than UTXO. Like you said this is probably necessary to support something like ECASH, and on card change making would come along for free.

Branded or Attested phonons could be implemented on top of the protocol today by utilizing a signature in the extended schema without the need for any card changes to support a different style of key derivation on card.

So really there are two independent good ideas here.

I shared some info with the DAO at the BETA kickoff meeting today. I will find a public place to keep our current roadmap/backlog in a public place so we can hopefully collaborate better on the critical path items to get us to a complete phonon implementation.