root / trunk / standards / protocol.txt

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

Referenced RFC 4086 and RFC 4627

Line 
1OpenCoin Project                                            N. Toedtmann
2http://opencoin.org/                                         J. H. Baach
3Category: Draft                                                 M. Ryden
4
5                      OpenCoin Formats and Protocol
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
16   Copyright (c) N. Toedtmann, J. H. Baach, M. Ryden (2008).
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
25ToDo
26
27   - licence of this document (GNU FDL, CC-BY-SA, Public Domain)?
28   - "Introduction", including scope of protocol
29   - JSON, 7-bit ASCII
30   - define token/certificate format, encryption padding
31   - define validity of certificates and tokens
32   - add note on randomness
33   - add PROTOCOL_ERROR
34   - add HANDSHAKE, CONTINUE, GOODBYE; warning that GOODBYE will disappear
35   - throw out reduntant "TRANSFER_TOKEN" explanatoins
36   - add authentication and authorization, at least for "target"
37     when minting
38   - add mandatory trusted channel (Bluetooth, TLS)
39   - reformat this into RFC-XML
40   - add warning on differences to scientific notation
41
42
43Table of Contents
44
45   1. Introduction
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
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 
57      3.5.  Wallet gets token back
58      3.6.  Wallet to wallet
59      3.7.  Redeeming tokens
60   4. References
61
62
631. Introduction
64
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
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.
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
92In the standard case of online payment, spending and redemption are actually
93entwined to one simultanious operation.
94
95Tokens include a reference to this protocol, a reference to the issuer, a
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.
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
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').
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
117[ToDo]
118
119
1201.3 General Layout of the OpenCoin protocol
121
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.
133
134The participants send each other messages in request/response pairs. The
135universal scheme is this:
136
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
1721.4 Encoding of messages, tokens and certificates
173
174[ToDo]
175
176
177
1782. General guidelines
179
180[ToDo]
181
182
1833. The OpenCoin protocol
184 
1853.1 Issuer setup
186
187* issuer generates master key pair (ALG,pM,sM)
188
189* issuer sets up "currency description document" = CDD (like a root certificate)
190
191   {
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
196     denominations                = strlist(1, 2, 5, 10, 20, 50, 100, 200, 500, 1000)  #list of strings seperated by commas
197     issuer cipher suite          = HASH-ALG, SIGN-ALG, BLINDING-ALG
198     issuer public master key     = base64(pM)
199     
200     issuer                       = base64(hash(pM))
201     base64(sig(sM,hash(content part)))
202   }
203
204   (question: is the "short currency identifier" needed?)
205   (question: "not use after")
206   (future: add additionial signatures, e.g. from wallet software vendors (set up in containers already))
207
208* issuer publishes CDD at "currency identifier" URL
209
210* mint (regularily) creates keypairs (pP,sP) for all denominations and id(p).
211  Master key holder generates keys certificate
212
213  {
214    key identifier      = base64(hash(pP))
215    currency identifier = http://opencent.net/OpenCent
216    denomination        = denomination
217    not_before          = TIME(...)
218    key_not_after       = TIME(...)
219    token_not_after      = TIME(...)
220    public key          = base64(pP)
221
222    issuer              = base64(hash(pM))
223    base64(sig(sM, hash(content part)))
224  }
225
226 
227  Questions:
228  * CDD?
229
230* issuer fires up issuer service (=IS) at <opencoin://issuer.opencent.net:8002>
231
232
2333.2 Wallet setup
234
235* fetch "currency description document" from issuer
236
237
2383.3 Wallet creates blanks
239
240* Wallet: fetches current public minting keys for denomination
241
242Wallet:
243    MINTING_KEY_FETCH_DENOMINATION(denomination) or MINTING_KEY_FETCH_KEYID(key_id)
244IS:
245    MINTING_KEY_PASS(keycertificate) or MINTING_KEY_FAILURE(reason)
246
247* Wallet: creates blank according to CDD:
248
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)
255  }
256
257
258* Wallet: create random r, calculate
259
260    blind = blinding(r, pub_minting_key, hash(blank))
261 
262  Calculate a collision-free random transaction ID (128 bit)
263
264  Keep (r, blank, blind) in mind.
265 
266
2673.3.5 "TRANSFER_TOKEN": A generic wallet-issuer request
268
269The atom for this transaction is a list of tokens - if one of the tokens /blanks
270fail, the whole transaction fails.
271
272* Client sends
273   
274        TRANSFER_TOKEN_REQUEST(
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
284  to IS (issuer service), where
285
286  * transaction_id is a base64(random(128bit)) referencing this transaction
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.
296
297  If at least one of the blinds or tokens is rejected, the issuer answers
298
299        TRANSFER_TOKEN_REJECT(
300            transaction_id, reason,
301            list( (blind1.key_id, reason1), ... ),
302            list( (token1.key_id,  reason1), ... )  )
303
304  where "reason" may be some general failure like "500 minting not available".
305  If the request is accepted with no delay, IS answers
306
307        TRANSFER_TOKEN_ACCEPT(
308            transaction_id, message, list_of_signed_blinds)
309
310  (with list_of_singed_blinds empty if no minting was required)
311  If minting was requested and acccepted but postponed, IS answers
312
313        TRANSFER_TOKEN_DELAY( transaction_id, message )
314
315  In this case, the wallet can fetch the signed blinds later by
316
317        TRANSFER_TOKEN_RESUME( transaction_id )
318
319
3203.4 Wallet send minting request to issuer 
321
322* Send
323
324        TRANSFER_TOKEN_REQUEST( transaction_id, target,
325            list_of_blinds+keyids, (empty list) , list_of_options, )
326
327  to issuer service
328
329* Issuer: if request will not be minted (e.g., "Bad Key ID" if the key_id
330  is not current):
331
332        TRANSFER_TOKEN_REJECT( transaction_id, reason,
333            list( (blind1.key_id, reason1), ... ), (empty list1)  )
334
335  ElseIf minting is done just-in-time, IS answers
336
337        TRANSFER_TOKEN_ACCEPT( transaction_id, message, list_of_signed_blinds)
338
339  Else IS queues blind to the mint and tells wallet to wait
340
341        TRANSFER_TOKEN_DELAY( transaction_id, reason )
342
343  Session is terminated.
344
345
346  In case of delayed minting, mint processes request (signs blind with key_id)
347  some time later and passes "signed blind"="blind token" back to IS
348
349
3503.5 Wallet gets token back
351
352* Wallet asks issuer service
353
354        TRANSFER_TOKEN_RESUME( transaction_id )
355
356* IS either rejects finally
357
358        TRANSFER_TOKEN_REJECT( transaction_id, reason,
359            list( (blind1.key_id, reason1), ... ), (empty list) )
360 
361  with reasons like "TID Unknown", "TID expired", "TID rejected", ...,
362  or tells to wait longer
363
364        TRANSFER_TOKEN_DELAY( transaction_id, reason )
365   
366  (question: what about key expiration while request is in mining queue)
367  (oierw thinks: as long as the key is valid for minting when the request is made, we are good)
368
369  or passes signed blinds to wallet Bob, must preserve order
370
371        TRANSFER_TOKEN_ACCEPT( transaction_id, message, list_of_singed_blinds )
372   
373  Session terminates
374
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
379* Wallet unblinds signed blind and yields token  (or reblinds)
380
381
3823.6 Wallet to wallet
383
384Alice - sends a token
385Bob   - receives the token
386
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. ]
390
391* Prerequisites
392  * Wallet Alice locates Wallet Bob and sets up (secure) connection
393  * Alice knows how much to send and tells her Wallet
394  * Wallet Alice calculates a splitting of sum into tokens (units)
395    and reates a list of tokens to send
396  * Wallet Alice and Wallet Bob are synchronized to UTC (within some small
397    margin of error)
398
399
400* [ToDo] Handshake
401
402
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:
405
406    A:      SUM_ANNOUNCE( transaction_id, sum, target )
407    B:      SUM_ACCEPT( transaction_id )
408        or  SUM_REJECT( transaction_id, "Reason" )
409
410
411* Wallet Alice sends tokens to Wallet Bob (this time including their clear
412  serial and signature)
413 
414    A:      SPEND_TOKEN_REQUEST( transaction_id, list(token1, ...) )
415
416* The atom for a SPEND_TOKEN_REQUEST is the entire list of tokens
417
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:
424
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 )
428
429  Possible reasons are "unknown", "invalid" ... [ToDo].
430
431  In case of rejection, wallet Alice itself should immediatly exchange these
432  tokens at the issuer as an emergancy countermeasure against token theft.
433
434  In case of acceptance, wallet Alice must delete all instances of the spent
435  tokens.
436
437
4383.7 Redeeming tokens
439
440* Wallet sends tokens + target to IS
441
442    W:  TRANSFER_TOKEN_REQUEST(
443            transaction_id, list_of_options, target, (empty list), list_of_tokens
444        )
445
446  target may be an account and is of the form:
447
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
452
453* IS checks if tokens and target are valid
454    - if minting keys are still valid (XXX token has not expired)
455    - if serial is still valid (against DSDB)
456    - if signature is valid
457
458  If not, IS rejects with reason (key id unknown, token outdated, token spent,
459  signature invalid) per token or sweeping
460
461    IS: TRANSFER_TOKEN_REJECT(
462            transaction_id, reason, (empty list), list( (token1.key_id,  reason1), ... )  )
463        )
464
465  If tokens and target are valid, IS enters the serials of the tokens into the
466  DSDB, servers the target and replies
467
468    IS: TRANSFER_TOKEN_ACCEPT(
469            transaction_id, message, (empty list)
470        )
471
472
4734. References
474
475[1]         The OpenCoin project <http://opencoin.org/>
476
477[2]         The OpenCoin project, "OpenCoin protocol v1.0"
478            <https://trac.opencoin.org/trac/opencoin/browser/trunk/standards/protocol.txt>
479
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.