root / trunk / standards / protocol.txt @ 214

Revision 214, 15.7 kB (checked in by ocnils, 2 years ago)

Referenced RFC 4086 and RFC 4627

RevLine 
[132]1OpenCoin Project                                            N. Toedtmann
2http://opencoin.org/                                         J. H. Baach
3Category: Draft                                                 M. Ryden
[1]4
[137]5                      OpenCoin Formats and Protocol
[132]6
7Status of this Memo
8
9   This draft is work in heavy progress. Do not consider it's content
10   stable in any sense as long as this note is present. Get in touch
11   with opencoin.org [1] and fetch a recent copy [2].
12   
13
14Copyright Notice
15
[137]16   Copyright (c) N. Toedtmann, J. H. Baach, M. Ryden (2008).
[132]17
18
19Abstract
20
21   This document describes the OpenCoin protocol which seeks to
22   implement David Chaum's concept of "untraceable payments" [3].
23
24
[75]25ToDo
26
[209]27   - licence of this document (GNU FDL, CC-BY-SA, Public Domain)?
[204]28   - "Introduction", including scope of protocol
29   - JSON, 7-bit ASCII
[208]30   - define token/certificate format, encryption padding
[209]31   - define validity of certificates and tokens
[207]32   - add note on randomness
33   - add PROTOCOL_ERROR
[204]34   - add HANDSHAKE, CONTINUE, GOODBYE; warning that GOODBYE will disappear
[132]35   - throw out reduntant "TRANSFER_TOKEN" explanatoins
[143]36   - add authentication and authorization, at least for "target"
[168]37     when minting
[143]38   - add mandatory trusted channel (Bluetooth, TLS)
[207]39   - reformat this into RFC-XML
[212]40   - add warning on differences to scientific notation
[75]41
[132]42
43Table of Contents
44
45   1. Introduction
[209]46      1.1  Object of the OpenCoin protocol
47      1.2  Limited scope of the OpenCoin protocol
48      1.3  General Layout of the OpenCoin protocol
49      1.4  Encoding of messages, tokens and certificates
[132]50   2. General guidelines
51   3. The OpenCoin protocol
52      3.1.  Issuer setup
53      3.2.  Wallet setup
54      3.3.  Wallet creates blanks
55      3.3.5."TRANSFER_TOKEN": A generic wallet-issuer request
56      3.4.  Wallet send minting request to issuer 
[142]57      3.5.  Wallet gets token back
58      3.6.  Wallet to wallet
59      3.7.  Redeeming tokens
[132]60   4. References
61
62
631. Introduction
64
[209]651.1 Object of the OpenCoin protocol
66
67The OpenCoin protocol aims to implement David Chaum's concept of "untraceable
68payments" [3]. The general procedure is this:
69
70* Minting
71  * A payer creates a yet unsigned, 'blank' token according to the rules
72    published by the issuer. It includes a serial number.
73  * He obfuscates this blank, yielding the 'blind'. He send the blind to the
74    issuer and request signing with a special minting key.
75  * If the issuer's requirements for minting (which may include a payment)
76    are met, he signs the payer's  blind with the nominated minting key.
77  * The payer fetches the signed blind from the issuer and 'unblinds'. The
78    result is a token including a valid signature from the issuer.
79
80* Spending
81    A payer sends the token to a payee. The payee verifies that the token is
[212]82    valid according to the issuer's rules (format, data, signature, ...). In
83    the standard online case, he also checks it against the issuer's double
84    spending database (DSDB). He tells the payer if he accepts the token.
[209]85
86* Redemption
87    The payee sends the token to the issuer. The issuer verifies that the
88    token is valid and checks it against his DSDB. If he accepts the token,
89    he adds its serial number to the DSDB. He may offer the payee something
90    in exchange for the token (like a payment).
91
[212]92In the standard case of online payment, spending and redemption are actually
93entwined to one simultanious operation.
[209]94
95Tokens include a reference to this protocol, a reference to the issuer, a
[212]96denomination, a random serial and the mint's signature over this data. The
97minting key used to sign the token is deticated to mint exclusivly tokens
98of this denomination.
[209]99
100This protocol is designed such that tokens are unforgable and untracable:
101
102* Unforgeability/balance
103  Without knowledge of the issuer's private minting keys, no combination of
104  payers and payees can successfully redeem tokens of a total denomination
[212]105  higher than the total denomination of tokens minted by the issuer for them.
106  In Particular, no one (except the issuer) can produce N+1 valid tokens
107  from N valid tokens ('one-more-forgery').
[209]108
109* Untraceability
110  No combination of the issuer and a set of payees are able to correlate
111  blinds and tokens of a payer just by looking at them (but maybe by traffic
112  analysis).
113
114
1151.2 Limited scope of the OpenCoin protocol
116
[132]117[ToDo]
118
119
[209]1201.3 General Layout of the OpenCoin protocol
121
[212]122The OpenCoin protocol typically involves three parties: the issuer, a sender/
123payer (Alice) and a receiver/payee (Bob). We call the OpenCoin user agents of
124payer and payee 'wallets'. The issuer consists of four parts:
125* The 'master key holder' (MHK) generates and keeps the master key pair
126  and signes and publishes the 'currency description document' (CDD) and
127  all the certificates.
128* The mint generates and keeps the minting keys and signes blinds.
129* The 'double spending database' (DSDB) keeps track of the serials of
130  tokens which got redeemed.
131* The 'issuer service' (IS) is the public interface of the issuer on the
132  internet.
[209]133
[212]134The participants send each other messages in request/response pairs. The
135universal scheme is this:
[209]136
[212]137     * session initiation *
138
139   -- [ HANDSHAKE, DATA ] -->
140  <-- [ HANDSHAKE, null ] --
141
142   -- [ REQUEST_1, DATA ] -->
143  <-- [ RESPONSE_1,DATA ] --
144
145   -- [ REQUEST_2, DATA ] -->
146  <-- [ RESPONSE_2,DATA ] --
147
148   -- [ CONTINUE,  null ] -->
149  <-- [ CONTINUE,  null ] --
150
151          * pause *
152
153   -- [ REQUEST_3, DATA ] -->
154  <-- [ RESPONSE_3,DATA ] --
155
156   -- [ REQUEST_4, DATA ] -->
157  <-- [ RESPONSE_4,DATA ] --
158
159   -- [ GOODBYE,   null ] -->
160  <-- [ GOODBYE,   null ] --
161
162     * session termination *
163
164The standard case involves three sessions:
165
166   Payer Alice  --[minting]--------------------------------->  Issuer
167   Payer Alice  --[spending]-->  Payee Bob  --[redemption]-->  Issuer
168
169the latter two usually happening at the same time ('online case').
170
171
[209]1721.4 Encoding of messages, tokens and certificates
173
174[ToDo]
175
176
177
[132]1782. General guidelines
179
180[ToDo]
181
182
1833. The OpenCoin protocol
[7]184 
[132]1853.1 Issuer setup
[1]186
[5]187* issuer generates master key pair (ALG,pM,sM)
[1]188
[5]189* issuer sets up "currency description document" = CDD (like a root certificate)
[1]190
191   {
[5]192     standard version             = http://opencoin.org/OpenCoinProtocol/1.0
193     currency identifier          = http://opencent.net/OpenCent
194     short currency identifier    = OC
195     issuer service location      = opencoin://issuer.opencent.net:8002
[19]196     denominations                = strlist(1, 2, 5, 10, 20, 50, 100, 200, 500, 1000)  #list of strings seperated by commas
[5]197     issuer cipher suite          = HASH-ALG, SIGN-ALG, BLINDING-ALG
198     issuer public master key     = base64(pM)
199     
[82]200     issuer                       = base64(hash(pM))
[5]201     base64(sig(sM,hash(content part)))
[1]202   }
203
[5]204   (question: is the "short currency identifier" needed?)
[82]205   (question: "not use after")
206   (future: add additionial signatures, e.g. from wallet software vendors (set up in containers already))
[1]207
[5]208* issuer publishes CDD at "currency identifier" URL
209
[34]210* mint (regularily) creates keypairs (pP,sP) for all denominations and id(p).
[5]211  Master key holder generates keys certificate
212
213  {
[82]214    key identifier      = base64(hash(pP))
[9]215    currency identifier = http://opencent.net/OpenCent
216    denomination        = denomination
217    not_before          = TIME(...)
218    key_not_after       = TIME(...)
[142]219    token_not_after      = TIME(...)
[34]220    public key          = base64(pP)
[5]221
[82]222    issuer              = base64(hash(pM))
[5]223    base64(sig(sM, hash(content part)))
224  }
225
[1]226 
[5]227  Questions:
[168]228  * CDD?
[1]229
[5]230* issuer fires up issuer service (=IS) at <opencoin://issuer.opencent.net:8002>
[1]231
232
[132]2333.2 Wallet setup
[1]234
235* fetch "currency description document" from issuer
236
237
[132]2383.3 Wallet creates blanks
[1]239
240* Wallet: fetches current public minting keys for denomination
241
[13]242Wallet:
[28]243    MINTING_KEY_FETCH_DENOMINATION(denomination) or MINTING_KEY_FETCH_KEYID(key_id)
[13]244IS:
[28]245    MINTING_KEY_PASS(keycertificate) or MINTING_KEY_FAILURE(reason)
[5]246
[1]247* Wallet: creates blank according to CDD:
248
[5]249  {
250      standard identifier = http://opencoin.org/OpenCoinProtocol/1.0
251      currency identifier = http://opencent.net/OpenCent
252      denomination        = denomination
253      key identifier      = key_id(signing key)
254      serial              = base64(128bit random number)
[1]255  }
256
257
258* Wallet: create random r, calculate
259
[5]260    blind = blinding(r, pub_minting_key, hash(blank))
[1]261 
[83]262  Calculate a collision-free random transaction ID (128 bit)
[5]263
[2]264  Keep (r, blank, blind) in mind.
265 
[71]266
[204]2673.3.5 "TRANSFER_TOKEN": A generic wallet-issuer request
[71]268
[142]269The atom for this transaction is a list of tokens - if one of the tokens /blanks
[80]270fail, the whole transaction fails.
271
[144]272* Client sends
[83]273   
[144]274        TRANSFER_TOKEN_REQUEST(
[205]275            transaction_id, target, list_of_blinds+keyids,
276            list_of_tokens, list_of_options )
277
278  [ WARNING: In future versions of this protocol, it wll change to
279        TRANSFER_TOKEN_REQUEST (
280            transaction_id, list_of_options,
281            target, list_of_blinds+keyids, list_of_tokens )
282  ]
283
[71]284  to IS (issuer service), where
[144]285
[71]286  * transaction_id is a base64(random(128bit)) referencing this transaction
[205]287    e.g. for later resume after an abort.
288  * list_of_option may contain variable=value pairs like "JITM=mandatory".
289    It must contain the option "type", which can have three values:
290    * mint    : A minting request. target is a payment reference,
291                list_of_tokens must be empty.
292    * redeem  : A token redemption. target is an account reference,
293                list_of_blinds+keyids must be empty.
294    * exchange: A request to mint new tokens for old ones. target must be
295                empty, value of blinds must equal value of tokens.
[71]296
[142]297  If at least one of the blinds or tokens is rejected, the issuer answers
[71]298
[205]299        TRANSFER_TOKEN_REJECT(
300            transaction_id, reason,
301            list( (blind1.key_id, reason1), ... ),
302            list( (token1.key_id,  reason1), ... )  )
[71]303
304  where "reason" may be some general failure like "500 minting not available".
[73]305  If the request is accepted with no delay, IS answers
306
[205]307        TRANSFER_TOKEN_ACCEPT(
308            transaction_id, message, list_of_signed_blinds)
[73]309
310  (with list_of_singed_blinds empty if no minting was required)
[72]311  If minting was requested and acccepted but postponed, IS answers
[71]312
[205]313        TRANSFER_TOKEN_DELAY( transaction_id, message )
[72]314
[73]315  In this case, the wallet can fetch the signed blinds later by
[72]316
[205]317        TRANSFER_TOKEN_RESUME( transaction_id )
[71]318
319
[132]3203.4 Wallet send minting request to issuer 
[1]321
[206]322* Send
[2]323
[205]324        TRANSFER_TOKEN_REQUEST( transaction_id, target,
325            list_of_blinds+keyids, (empty list) , list_of_options, )
[1]326
327  to issuer service
328
[74]329* Issuer: if request will not be minted (e.g., "Bad Key ID" if the key_id
330  is not current):
[1]331
[205]332        TRANSFER_TOKEN_REJECT( transaction_id, reason,
333            list( (blind1.key_id, reason1), ... ), (empty list1)  )
[1]334
[74]335  ElseIf minting is done just-in-time, IS answers
[1]336
[205]337        TRANSFER_TOKEN_ACCEPT( transaction_id, message, list_of_signed_blinds)
[1]338
[74]339  Else IS queues blind to the mint and tells wallet to wait
[1]340
[205]341        TRANSFER_TOKEN_DELAY( transaction_id, reason )
[1]342
[74]343  Session is terminated.
[5]344
345
[74]346  In case of delayed minting, mint processes request (signs blind with key_id)
[142]347  some time later and passes "signed blind"="blind token" back to IS
[5]348
349
[142]3503.5 Wallet gets token back
[1]351
[206]352* Wallet asks issuer service
[1]353
[205]354        TRANSFER_TOKEN_RESUME( transaction_id )
[5]355
[76]356* IS either rejects finally
[1]357
[205]358        TRANSFER_TOKEN_REJECT( transaction_id, reason,
359            list( (blind1.key_id, reason1), ... ), (empty list) )
[5]360 
[76]361  with reasons like "TID Unknown", "TID expired", "TID rejected", ...,
362  or tells to wait longer
[5]363
[205]364        TRANSFER_TOKEN_DELAY( transaction_id, reason )
[76]365   
[6]366  (question: what about key expiration while request is in mining queue)
[82]367  (oierw thinks: as long as the key is valid for minting when the request is made, we are good)
[5]368
[6]369  or passes signed blinds to wallet Bob, must preserve order
370
[205]371        TRANSFER_TOKEN_ACCEPT( transaction_id, message, list_of_singed_blinds )
[28]372   
[6]373  Session terminates
[5]374
[1]375* wallet checks if blind fits request id and if blind was correctly signed.
376  If not, delete blind and inform user (optional: inform issuer about error)
377  (optional: if yes, inform issuer that he may delete the request)
378
[142]379* Wallet unblinds signed blind and yields token  (or reblinds)
[1]380
[2]381
[142]3823.6 Wallet to wallet
[2]383
[142]384Alice - sends a token
385Bob   - receives the token
[2]386
[208]387  [ Warning:
388    The messages "SPEND_TOKEN_*" may get exchanged by "TRANSFER_TOKEN_*" of
389    type "redeem" or "spend" in future versions of this protocol. ]
[139]390
391* Prerequisites
[5]392  * Wallet Alice locates Wallet Bob and sets up (secure) connection
393  * Alice knows how much to send and tells her Wallet
[142]394  * Wallet Alice calculates a splitting of sum into tokens (units)
395    and reates a list of tokens to send
[139]396  * Wallet Alice and Wallet Bob are synchronized to UTC (within some small
397    margin of error)
[2]398
[6]399
[139]400* [ToDo] Handshake
[2]401
402
[139]403* Wallet Alice announces sum of tokens she wishes to spend for a certain
404  prupose=target, wallet Bob decides if it is going to accept them:
[9]405
[139]406    A:      SUM_ANNOUNCE( transaction_id, sum, target )
407    B:      SUM_ACCEPT( transaction_id )
408        or  SUM_REJECT( transaction_id, "Reason" )
[9]409
[2]410
[142]411* Wallet Alice sends tokens to Wallet Bob (this time including their clear
[139]412  serial and signature)
413 
[208]414    A:      SPEND_TOKEN_REQUEST( transaction_id, list(token1, ...) )
[2]415
[208]416* The atom for a SPEND_TOKEN_REQUEST is the entire list of tokens
[80]417
[139]418* Wallet Bob checks if the sum of their values matches the announced sum, if
419  they are valid and (if the former tests do not fail) tries itself to spent
420  the tokens at the issuer with a TRANSFER_TOKEN_REQUEST of type "redeem" or
421  "exchange", using a new, different transaction_id. If one of these fail,
422  wallet Bob rejects the request it with a reason/reasons, otherwise accepts
423  them:
[2]424
[208]425    B:      SPEND_TOKEN_REJECT( transaction_id, list( (tokenN, "ReasonN") ) )
426        or  SPEND_TOKEN_REJECT( transaction_id, emptylist, "Reason")
427        or  SPEND_TOKEN_ACCEPT( transaction_id )
[80]428
[139]429  Possible reasons are "unknown", "invalid" ... [ToDo].
[2]430
[139]431  In case of rejection, wallet Alice itself should immediatly exchange these
432  tokens at the issuer as an emergancy countermeasure against token theft.
[2]433
[139]434  In case of acceptance, wallet Alice must delete all instances of the spent
435  tokens.
[77]436
[139]437
[142]4383.7 Redeeming tokens
[77]439
[142]440* Wallet sends tokens + target to IS
[2]441
[141]442    W:  TRANSFER_TOKEN_REQUEST(
[142]443            transaction_id, list_of_options, target, (empty list), list_of_tokens
[141]444        )
[2]445
[141]446  target may be an account and is of the form:
[77]447
[9]448        MINT_REQUEST=#base64(request_id)
449        ONLINE_BANKING_ACCOUNT=#string(account_identifier)
450        and so on... to be defined with relationship between IS and individual
451
[2]452
[141]453* IS checks if tokens and target are valid
[142]454    - if minting keys are still valid (XXX token has not expired)
[2]455    - if serial is still valid (against DSDB)
456    - if signature is valid
457
[142]458  If not, IS rejects with reason (key id unknown, token outdated, token spent,
459  signature invalid) per token or sweeping
[2]460
[141]461    IS: TRANSFER_TOKEN_REJECT(
[142]462            transaction_id, reason, (empty list), list( (token1.key_id,  reason1), ... )  )
[141]463        )
[77]464
[141]465  If tokens and target are valid, IS enters the serials of the tokens into the
466  DSDB, servers the target and replies
[2]467
[141]468    IS: TRANSFER_TOKEN_ACCEPT(
469            transaction_id, message, (empty list)
470        )
[2]471
472
[132]4734. References
474
[214]475[1]         The OpenCoin project <http://opencoin.org/>
[132]476
[214]477[2]         The OpenCoin project, "OpenCoin protocol v1.0"
478            <https://trac.opencoin.org/trac/opencoin/browser/trunk/standards/protocol.txt>
[132]479
[214]480[3]         David Chaum, "Blind signatures for untraceable payments", Advances
481            in Cryptology - Crypto '82, Springer-Verlag (1983), 199-203.
482
483[RFC4086]   D. Eastlake, J. Schiller and S. Crocker, "Randomness Requirements
484            for Security", RFC 4086, June 2005
485
486[RFC4627]   D. Crockford, "The application/json Media Type for JavaScript
487            Object Notation (JSON)", RFC 4627, July 2006
Note: See TracBrowser for help on using the browser.