OpenCoin protocol#


The exchange of messages MUST happen over a secure channel. For HTTPS this means TLS, but other channels, like messengers, will most likely provide their own. For an email exchange GPG would be recommended.

Either way, it is the responsibility of the developer to take care of the transport security.

When requesting the issuer to mint or redeem coins some form of authentication & authorization is most likely required - the issuer needs to secure payment for the coins, or make a payment somewhere for redeemed coins. Because auth* might already be provided by the transport layer, we don’t include it in the OpenCoin protocol.

Sequence diagram#

The following OpenCoin sequence diagram shows the flow of messages (and actions).

OpenCoin sequence

OpenCoin sequence diagram#

Protocol description#

This is a description of the actual steps. Additional info for individual steps can also be found in the respective sections in Schemata. 1We find it easier to follow along with the above diagram open in a second window (or printout).


Issuer can mint, refresh and redeem coins. This entity will probably have an account handling system (a.k.a. bank) behind it for doing actual real-world payments. The issuer is trusted to handle coins and payments correctly, but is not trusted regarding privacy - the target of OpenCoin is to protect the privacy of the transfers.

Alice and Bob are clients using OpenCoin. Technically they are client software called “wallets”, and they represent the users of the system.2To keep the diagram simple we have left out Charlene who was mentioned above in “How does it work?”. Bob does everything she does. They need to be authenticated by the Issuer in order to mint or redeem coins. To renew coin authentication is optional, and would allow a “closed” system, in which accounts of the users could be monitored quite closely.

Steps in the protocol#

create CDDC#

The issuer creates a pair of cryptographic keys (the currency keys), and signs a Currency Description Document Certificate (CDDC) with its secret key. The CDDC contains information about the currency, like denominations, urls but also the public key. This is the top document which establishes the trust in all other elements.

Not mentioned in the CDDC but probably somewhere on the issuer website are the rules for the relation between opencoins and actual real-world money. Let’s say the currency of an example issuer is called “opencent”.3“opencent” refers to the specific example currency. The generic term “opencoin” refers to any currency following the OpenCoin protocol (of which opencent is one). The rule might be that one opencent is given out for 0.01 EUR , and redeemed for 0.01 EUR, effectively binding the opencent to the EUR.

create MKCs#

For each denomination in the currency separate minting keys are generated, and a Mint Key Certificate (MKC) for them as well. Those MKCs are signed using the secret currency key. The mint keys are only valid for a defined period of time.4This is to minimize damage in case the mint keys get compromised.


RequestCDDCSerial asks for the current serial number of the CDDC. The currency description could change over time, maybe because urls have changed. On every change a new CDDC is created, with a new, increasing serial number. The clients need to make sure to always use the most current CDDC, but they can cache it, allowing them to skip the next step.


ResponseCDDSerial contains the current serial of the CDDC.


RequestCDDC asks for a CDDC. If no serial is provided, the message asks for the most current CDDC.


ResponseCDDC contains the CDDC


RequestMKCs asks for the Mint Key Certificates. The client can specify specific denominations or mint key ids. An unspecified request will return all current MKCs.


ResponseMCKs contains the MKCs

prepare blinds#

This step prepares a coin. In essence this is a Payload containing a serial number, which is later on signed by the issuer using a denomination specific mint key. The “envelope” mentioned above really means that the serial is blinded using a separate random secret blinding factor for each serial number. This factor is needed later on to “open up the envelope”, reversing the blinding operation. Hence, the client has to store the blinding factor for later on. As the blinding factor is individual for each serial number, a reference number is created to reference serial, blinding factor and Blind.

The blinds contain the reference, the Blind to be signed, and the mint key id for the denomination or value of the coin.


RequestMint hands in the Blinds created in the step before, asking for the blind to be signed.

Most likely the issuer has authenticated the client. The mint key id tells the Issuer what denomination to use for the signing operation. This will allow the Issuer to deduct a payment for the minting operation (outside OpenCoin).

The message also carries a transaction_reference (a random number), which is used in case of a delay in the minting process. The client can then later on ask again for the signatures to be delivered using the same transaction_reference.

sign blinds#

The issuer uses the secret minting key for the desired operation to sign the Blind, creating Blind Signatures.


ResponseMint contains the Blind Signatures for the Blinds.


The client will unblind the Blind Signature using the before stored secret blinding factor. This gives the client the signature for the serial number, and both together make up the Coin. The signature is validated by Alice.


When sending coins, multiple coins can be combined into a CoinStack. This CoinStack can also have a “subject”, a note on the reason the CoinStack is handed over in the first place, maybe containing an order reference.

The transfer of the CoinStack is out of scope of the OpenCoin protocol. We imagine multiple ways: using a messenger like Signal, using email or using the Browser. A CoinStack can also be encoded using a QR code, and maybe printed out and sent using normal postal mail.

Anyhow, the point of this step is that Alice transfers a CoinStack to Bob. And because she is a fair user, she will delete all coins that were contained in the CoinStack on her side.


Coins that are received need to be swapped for new ones, in order to protect the receiver against double spending. Bob needs to decide which new coin sizes he needs to have. He tokenizes the amount in the right way to have a good selection of future coin sizes (he wants the right change in his wallet to pay all possible future amounts). 5It might be that also some existing coins might be needed to be swapped to get a good coin selection. See RequestRenew Message.

prepare blinds#

Knowing the right coin selection from the step before Bob prepares Blinds the same way Alice has done with hers, creating Payloads (containing serials), and indexing the blinding secrets using a reference.


The renewal process is effectively the same as in minting new coins, but it is paid for in opencoins, instead of making a payment in the background using accounts. Hence, the RequestRenew message needs to contain Coins that have a value that matches the sum of value of the Blinds. The message also contains a transaction_reference in case a delay happens.


This step is optional.

If something takes a while at the issuer when signing the blinds, either while handling a RequestMint or RequestRenew a ResponseDelay can be sent back to indicate that the client should try again sometime later. This allows the network connection be closed in the meantime. Hopefully operations resume in a short time.

Delays should be avoided on the issuer side.


Bob will try some time later on to resume the transaction (the renewal in this case). The RequestResume message will send over the transaction reference, and the issuer will hopefully respond with a ResponseMint message, or with another ResponseDelay.

validate coins#

Bob validates the Coins, just as Alice did.


Bob might want to convert some or all of the Coins he holds for real-world currency at the issuer. He sends in the coins in a RequestRedeem message. This effectively takes the coins out of circulation, and the issuer will make a payment to Bob’s account. This requires the client to be authenticated for this step, which again is outside the OpenCoin protocol.


The issuer confirms that everything went ok using the ResponseRedeem message.