lsd0009

LSD0009: The GNU Taler Protocol
Log | Files | Refs | README

draft-guetschow-taler-protocol.xml (41978B)


      1 <?xml version='1.0' encoding='utf-8'?>
      2 <!DOCTYPE rfc [
      3   <!ENTITY nbsp    "&#160;">
      4   <!ENTITY zwsp   "&#8203;">
      5   <!ENTITY nbhy   "&#8209;">
      6   <!ENTITY wj     "&#8288;">
      7 ]>
      8 <?xml-stylesheet type="text/xsl" href="rfc2629.xslt" ?>
      9 <!-- generated by https://github.com/cabo/kramdown-rfc version 1.7.35 (Ruby 3.1.2) -->
     10 <rfc xmlns:xi="http://www.w3.org/2001/XInclude" ipr="trust200902" docName="draft-guetschow-taler-protocol" category="info" submissionType="independent" tocInclude="true" sortRefs="true" symRefs="true" version="3">
     11   <!-- xml2rfc v2v3 conversion 3.32.0 -->
     12   <front>
     13     <title>The GNU Taler Protocol</title>
     14     <seriesInfo name="Internet-Draft" value="draft-guetschow-taler-protocol"/>
     15     <author initials="M." surname="Gütschow" fullname="Mikolai Gütschow">
     16       <organization abbrev="TU Dresden">TUD Dresden University of Technology</organization>
     17       <address>
     18         <postal>
     19           <street>Helmholtzstr. 10</street>
     20           <city>Dresden</city>
     21           <code>D-01069</code>
     22           <country>Germany</country>
     23         </postal>
     24         <email>mikolai.guetschow@tu-dresden.de</email>
     25       </address>
     26     </author>
     27     <date year="2026" month="April" day="02"/>
     28     <workgroup>independent</workgroup>
     29     <keyword>taler</keyword>
     30     <keyword>cryptography</keyword>
     31     <keyword>ecash</keyword>
     32     <keyword>payments</keyword>
     33     <abstract>
     34       <?line 43?>
     35 
     36 <t>[ TBW ]</t>
     37     </abstract>
     38   </front>
     39   <middle>
     40     <?line 47?>
     41 
     42 <section anchor="introduction">
     43       <name>Introduction</name>
     44       <t>[ TBW ]</t>
     45       <t>Beware that this document is still work-in-progress and may contain errors.
     46 Use at your own risk!</t>
     47     </section>
     48     <section anchor="notation">
     49       <name>Notation</name>
     50       <ul spacing="normal">
     51         <li>
     52           <t><tt>"abc"</tt> denotes the literal string <tt>abc</tt> encoded as ASCII <xref target="RFC20"/></t>
     53         </li>
     54         <li>
     55           <t><tt>a | b</tt> denotes the concatenation of a with b</t>
     56         </li>
     57         <li>
     58           <t><tt>len(a)</tt> denotes the length in bytes of the byte string a</t>
     59         </li>
     60         <li>
     61           <t><tt>padZero(y, a)</tt> denotes the byte string a, zero-padded to the length of y bytes</t>
     62         </li>
     63         <li>
     64           <t><tt>bits(x)</tt>/<tt>bytes(x)</tt> denotes the minimal number of bits/bytes necessary to represent the multiple precision integer x</t>
     65         </li>
     66         <li>
     67           <t><tt>uint(y, x)</tt> denotes the <tt>y</tt> least significant bits of the integer <tt>x</tt> encoded in network byte order (big endian)</t>
     68         </li>
     69         <li>
     70           <t><tt>uint16(x)</tt>/<tt>uint32(x)</tt>/<tt>uint64(x)</tt>/<tt>uint256(x)</tt>/<tt>uint512(x)</tt> is equivalent to <tt>uint(16, x)</tt>/<tt>uint(32, x)</tt>/<tt>uint(64, x)</tt>/<tt>uint(256, x)</tt>/<tt>uint(512, x)</tt>, respectively</t>
     71         </li>
     72         <li>
     73           <t><tt>random(y)</tt> denotes a randomly generated sequence of y bits</t>
     74         </li>
     75         <li>
     76           <t><tt>a * b (mod N)</tt> / <tt>a ** b (mod N)</tt> denotes the multiplication / exponentiation of multiple precision integers a and b, modulo N</t>
     77         </li>
     78       </ul>
     79     </section>
     80     <section anchor="cryptographic-primitives">
     81       <name>Cryptographic Primitives</name>
     82       <section anchor="cryptographic-hash-functions">
     83         <name>Cryptographic Hash Functions</name>
     84         <section anchor="sha256">
     85           <name>SHA-256</name>
     86           <artwork><![CDATA[
     87 SHA-256(msg) -> hash
     88 
     89 Input:
     90     msg     input message of length L < 2^61 octets
     91 
     92 Output:
     93     hash    message digest of fixed length HashLen = 32 octets
     94 ]]></artwork>
     95           <t><tt>hash</tt> is the output of SHA-256 as per Sections 4.1, 5.1, 6.1, and 6.2 of <xref target="RFC6234"/>.</t>
     96         </section>
     97         <section anchor="sha512">
     98           <name>SHA-512</name>
     99           <artwork><![CDATA[
    100 SHA-512(msg) -> hash
    101 
    102 Input:
    103     msg     input message of length L < 2^125 octets
    104 
    105 Output:
    106     hash    message digest of fixed length HashLen = 64 octets
    107 ]]></artwork>
    108           <t><tt>hash</tt> is the output of SHA-512 as per Sections 4.2, 5.2, 6.3, and 6.4 of <xref target="RFC6234"/>.</t>
    109         </section>
    110         <section anchor="sha512-trunc">
    111           <name>SHA-512-256 (truncated SHA-512)</name>
    112           <artwork><![CDATA[
    113 SHA-512-256(msg) -> hash
    114 
    115 Input:
    116     msg     input message of length L < 2^125 octets
    117 
    118 Output:
    119     hash    message digest of fixed length HashLen = 32 octets
    120 ]]></artwork>
    121           <t>The output <tt>hash</tt> corresponds to the first 32 octets of the output of SHA-512 defined in <xref target="sha512"/>:</t>
    122           <artwork><![CDATA[
    123 temp = SHA-512(msg)
    124 hash = temp[0:31]
    125 ]]></artwork>
    126           <t>Note that this operation differs from SHA-512/256 as defined in <xref target="SHS"/> in the initial hash value.</t>
    127         </section>
    128       </section>
    129       <section anchor="message-authentication-codes">
    130         <name>Message Authentication Codes</name>
    131         <section anchor="hmac">
    132           <name>HMAC</name>
    133           <artwork><![CDATA[
    134 HMAC-Hash(key, text) -> out
    135 
    136 Option:
    137     Hash    cryptographic hash function with output length HashLen
    138 
    139 Input:
    140     key     secret key of length at least HashLen
    141     text    input data of arbitary length
    142 
    143 Output:
    144     out     output of length HashLen
    145 ]]></artwork>
    146           <t><tt>out</tt> is calculated as defined in <xref target="RFC2104"/>.</t>
    147         </section>
    148       </section>
    149       <section anchor="key-derivation-functions">
    150         <name>Key Derivation Functions</name>
    151         <section anchor="hkdf">
    152           <name>HKDF</name>
    153           <t>The Hashed Key Derivation Function (HKDF) used in Taler is an instantiation of <xref target="RFC5869"/>
    154 with two different hash functions for the Extract and Expand step as suggested in <xref target="HKDF"/>:
    155 <tt>HKDF-Extract</tt> uses <tt>HMAC-SHA512</tt>, while <tt>HKDF-Expand</tt> uses <tt>HMAC-SHA256</tt> (cf. <xref target="hmac"/>).</t>
    156           <artwork><![CDATA[
    157 HKDF(salt, IKM, info, L) -> OKM
    158 
    159 Inputs:
    160     salt    optional salt value (a non-secret random value);
    161               if not provided, it is set to a string of 64 zeros.
    162     IKM     input keying material
    163     info    optional context and application specific information
    164               (can be a zero-length string)
    165     L       length of output keying material in octets
    166               (<= 255*32 = 8160)
    167 
    168 Output:
    169     OKM      output keying material (of L octets)
    170 ]]></artwork>
    171           <t>The output OKM is calculated as follows:</t>
    172           <artwork><![CDATA[
    173 PRK = HKDF-Extract(salt, IKM) with Hash = SHA-512 (HashLen = 64)
    174 OKM = HKDF-Expand(PRK, info, L) with Hash = SHA-256 (HashLen = 32)
    175 ]]></artwork>
    176         </section>
    177         <section anchor="hkdf-mod">
    178           <name>HKDF-Mod</name>
    179           <t>Based on the HKDF defined in <xref target="hkdf"/>, this function returns an OKM that is smaller than a given multiple precision integer N.</t>
    180           <artwork><![CDATA[
    181 HKDF-Mod(N, salt, IKM, info) -> OKM
    182 
    183 Inputs:
    184     N        multiple precision integer
    185     salt     optional salt value (a non-secret random value);
    186               if not provided, it is set to a string of 64 zeros.
    187     IKM      input keying material
    188     info     optional context and application specific information
    189               (can be a zero-length string)
    190 
    191 Output:
    192     OKM      output keying material (smaller than N)
    193 ]]></artwork>
    194           <t>The final output <tt>OKM</tt> is determined deterministically based on a counter initialized at zero.</t>
    195           <artwork><![CDATA[
    196 counter = 0
    197 do until OKM < N:
    198     x = HKDF(salt, IKM, info | uint16(counter), bytes(N))
    199     OKM = uint(bits(N), x)
    200     counter += 1
    201 ]]></artwork>
    202         </section>
    203       </section>
    204       <section anchor="non-blind-signatures">
    205         <name>Non-Blind Signatures</name>
    206         <section anchor="ed25519">
    207           <name>Ed25519</name>
    208         </section>
    209       </section>
    210       <section anchor="blind-signatures">
    211         <name>Blind Signatures</name>
    212         <section anchor="rsa-fdh">
    213           <name>RSA-FDH</name>
    214           <section anchor="supporting-functions">
    215             <name>Supporting Functions</name>
    216             <artwork><![CDATA[
    217 RSA-FDH(msg, pubkey) -> fdh
    218 
    219 Inputs:
    220     msg     message
    221     pubkey  RSA public key consisting of modulus N and public exponent e
    222 
    223 Output:
    224     fdh     full-domain hash of msg over pubkey.N
    225 ]]></artwork>
    226             <t><tt>fdh</tt> is calculated based on HKDF-Mod from <xref target="hkdf-mod"/> as follows:</t>
    227             <artwork><![CDATA[
    228 info = "RSA-FDA FTpsW!"
    229 salt = uint16(bytes(pubkey.N)) | uint16(bytes(pubkey.e))
    230      | pubkey.N | pubkey.e
    231 fdh = HKDF-Mod(pubkey.N, salt, msg, info)
    232 ]]></artwork>
    233             <t>The resulting <tt>fdh</tt> can be used to test against a malicious RSA pubkey
    234 by verifying that the greatest common denominator (gcd) of <tt>fdh</tt> and <tt>pubkey.N</tt> is 1.</t>
    235             <artwork><![CDATA[
    236 RSA-FDH-Derive(bks, pubkey) -> out
    237 
    238 Inputs:
    239     bks     blinding key secret of length L = 32 octets
    240     pubkey  RSA public key consisting of modulus N and public exponent e
    241 
    242 Output:
    243     out     full-domain hash of bks over pubkey.N
    244 ]]></artwork>
    245             <t><tt>out</tt> is calculated based on HKDF-Mod from <xref target="hkdf-mod"/> as follows:</t>
    246             <artwork><![CDATA[
    247 info = "Blinding KDF"
    248 salt = "Blinding KDF extractor HMAC key"
    249 fdh = HKDF-Mod(pubkey.N, salt, bks, info)
    250 ]]></artwork>
    251           </section>
    252           <section anchor="blinding">
    253             <name>Blinding</name>
    254             <artwork><![CDATA[
    255 RSA-FDH-Blind(msg, bks, pubkey) -> out
    256 
    257 Inputs:
    258     msg     message
    259     bks     blinding key secret of length L = 32 octets
    260     pubkey  RSA public key consisting of modulus N and public exponent e
    261 
    262 Output:
    263     out     message blinded for pubkey
    264 ]]></artwork>
    265             <t><tt>out</tt> is calculated based on RSA-FDH from <xref target="rsa-fdh"/> as follows:</t>
    266             <artwork><![CDATA[
    267 data = RSA-FDH(msg, pubkey)
    268 r = RSA-FDH-Derive(bks, pubkey)
    269 r_e = r ** pubkey.e (mod pubkey.N)
    270 out = r_e * data (mod pubkey.N)
    271 ]]></artwork>
    272           </section>
    273           <section anchor="signing">
    274             <name>Signing</name>
    275             <artwork><![CDATA[
    276 RSA-FDH-Sign(data, privkey) -> sig
    277 
    278 Inputs:
    279     data    data to be signed, an integer smaller than privkey.N
    280     privkey RSA private key consisting of modulus N and private exponent d
    281 
    282 Output:
    283     sig     signature on data by privkey
    284 ]]></artwork>
    285             <t><tt>sig</tt> is calculated as follows:</t>
    286             <artwork><![CDATA[
    287 sig = data ** privkey.d (mod privkey.N)
    288 ]]></artwork>
    289           </section>
    290           <section anchor="unblinding">
    291             <name>Unblinding</name>
    292             <artwork><![CDATA[
    293 RSA-FDH-Unblind(sig, bks, pubkey) -> out
    294 
    295 Inputs:
    296     sig     blind signature
    297     bks     blinding key secret of length L = 32 octets
    298     pubkey  RSA public key consisting of modulus N and public exponent e
    299 
    300 Output:
    301     out     unblinded signature
    302 ]]></artwork>
    303             <t><tt>out</tt> is calculated as follows:</t>
    304             <artwork><![CDATA[
    305 r = RSA-FDH-Derive(bks, pubkey)
    306 r_inv = inverse of r (mod pubkey.N)
    307 out = sig * r_inv (mod pubkey.N)
    308 ]]></artwork>
    309           </section>
    310           <section anchor="verifying">
    311             <name>Verifying</name>
    312             <artwork><![CDATA[
    313 RSA-FDH-Verify(msg, sig, pubkey) -> out
    314 
    315 Inputs:
    316     msg     message
    317     sig     signature of pubkey over msg
    318     pubkey  RSA public key consisting of modulus N and public exponent e
    319 
    320 Output:
    321     out     true, if sig is a valid signature
    322 ]]></artwork>
    323             <t><tt>out</tt> is calculated based on RSA-FDH from <xref target="rsa-fdh"/> as follows:</t>
    324             <artwork><![CDATA[
    325 data = RSA-FDH(msg, pubkey)
    326 exp = sig ** pubkey.e (mod pubkey.N)
    327 out = (data == exp)
    328 ]]></artwork>
    329           </section>
    330         </section>
    331         <section anchor="clause-schnorr">
    332           <name>Clause-Schnorr</name>
    333         </section>
    334       </section>
    335     </section>
    336     <section anchor="datatypes">
    337       <name>Datatypes</name>
    338       <section anchor="amount">
    339         <name>Amount</name>
    340         <t>Amounts are represented in Taler as positive fixed-point values
    341 consisting of <tt>value</tt> as the non-negative integer part of the base currency,
    342 the <tt>fraction</tt> given in units of one hundred millionth (1e-8) of the base currency,
    343 and <tt>currency</tt> as the 3-11 ASCII characters identifying the currency.</t>
    344         <t>Whenever used in the protocol, the binary representation of an <tt>amount</tt> is
    345 <tt>uint64(amount.value) | uint32(amount.fraction) | padZero(12, amount.currency)</tt>.</t>
    346       </section>
    347       <section anchor="timestamps">
    348         <name>Timestamps</name>
    349         <t>Absolute timestamps are represented as <tt>uint64(x)</tt> where <tt>x</tt> corresponds to
    350 the microseconds since <tt>1970-01-01 00:00 CEST</tt> (the UNIX epoch).
    351 The special value <tt>0xFFFFFFFFFFFFFFFF</tt> represents "never".
    352 <!--
    353 // todo: check if needed and correct
    354 Relative timestamps are represented as `uint64(x)` where `x` is given in microseconds.
    355 The special value `0xFFFFFFFFFFFFFFFF` represents "forever".
    356 -->
    357         </t>
    358       </section>
    359       <section anchor="signatures">
    360         <name>Signatures</name>
    361         <t>All messages to be signed in Taler start with a header containing their size and
    362 a fixed signing context (purpose) as registered by GANA in the
    363 <eref target="https://gana.gnunet.org/gnunet-signatures/gnunet_signatures.html">GNUnet Signature Purposes</eref>
    364 registry. Taler-related purposes start at 1000.</t>
    365         <artwork><![CDATA[
    366 Sign-Msg(purpose, msg) -> out
    367 
    368 Inputs:
    369     purpose signature purpose as registered at GANA
    370     msg     message content (excl. header) to be signed
    371 
    372 Output:
    373     out     complete message (incl. header) to be signed
    374 ]]></artwork>
    375         <t><tt>out</tt> is formed as follows:</t>
    376         <artwork><![CDATA[
    377 out = uint32(len(msg)) | uint32(purpose) | msg
    378 ]]></artwork>
    379         <t>// todo: explain persist, check, knows, sum, indexing (if left of equal sign, single entry; if not refers to whole list)</t>
    380       </section>
    381     </section>
    382     <section anchor="the-taler-crypto-protocol">
    383       <name>The Taler Crypto Protocol</name>
    384       <section anchor="withdrawal">
    385         <name>Withdrawal</name>
    386         <t>The wallet generates <tt>n &gt; 0</tt> coins (<tt>coinᵢ</tt>) and requests <tt>n</tt> signatures (<tt>blind_sigᵢ</tt>) from the exchange,
    387 attributing value to the coins according to <tt>n</tt> chosen denominations (<tt>denomᵢ</tt>).
    388 The total value and withdrawal fee (defined by the exchange per denomination)
    389 must be smaller or equal to the amount stored in the single reserve used for withdrawal.</t>
    390         <t>// todo: extend with extra roundtrip for CBS</t>
    391         <artwork><![CDATA[
    392             wallet                                  exchange
    393 knows denomᵢ.pub                        knows denomᵢ.priv
    394                |                                        |
    395 +-----------------------------+                         |
    396 | (W1) reserve key generation |                         |
    397 +-----------------------------+                         |
    398                |                                        |
    399                |----------- (bank transfer) ----------->|
    400                | (subject: reserve.pub, amount: value)  |
    401                |                                        |
    402                |                      +------------------------------+
    403                |                      | persist (reserve.pub, value) |
    404                |                      +------------------------------+
    405                |                                        |
    406 +-----------------------------------+                   |
    407 | (W2) coin generation and blinding |                   |
    408 +-----------------------------------+                   |
    409                |                                        |
    410                |-------------- /withdraw -------------->|
    411                |    (reserve.pub, ~(coinᵢ.h_denom),     |
    412                |           ~blind_coin, sig0)           |
    413                |                                        |
    414                |                      +--------------------------------+
    415                |                      | (E1) coin issuance and signing |
    416                |                      +--------------------------------+
    417                |                                        |
    418                |<----------- (~blind_sig) --------------|
    419                |                                        |
    420 +----------------------+                                |
    421 | (W3) coin unblinding |                                |
    422 +----------------------+                                |
    423                |                                        |
    424 ]]></artwork>
    425         <t>where (for RSA, without age-restriction)</t>
    426         <artwork><![CDATA[
    427 (W1) reserve key generation (wallet)
    428 
    429 reserve = EdDSA-Keygen()
    430 persist (reserve, value)
    431 ]]></artwork>
    432         <t>The wallet derives coins and blinding secrets using a HKDF from a single master secret per withdrawal operation,
    433 together with an integer index.
    434 This is strictly speaking an implementation detail since the master secret is never revealed to any other party,
    435 and might be chosen to be implemented differently.</t>
    436         <artwork><![CDATA[
    437 (W2) coin generation and blinding (wallet)
    438 
    439 master_secret = random(256)
    440 persist master_secret
    441 coin_seedᵢ = HKDF(uint32(i), master_secret, "taler-withdrawal-coin-derivation", 64)
    442 blind_secretᵢ = coin_seedᵢ[32:]
    443 coinᵢ.priv = coin_seedᵢ[:32]
    444 coinᵢ.pub = EdDSA-GetPub(coinᵢ.priv)
    445 coinᵢ.h_denom = SHA-512(uint32(0) | uint32(1) | denomᵢ.pub)
    446 blind_coinᵢ = RSA-FDH-Blind(SHA-512(coinᵢ.pub), blind_secretᵢ, denomᵢ.pub)
    447 msg = Sign-Msg(WALLET_RESERVE_WITHDRAW,
    448     ( sum(denomᵢ.value) | sum(denomᵢ.fee_withdraw)
    449     | SHA-512( SHA-512(~(denomᵢ.pub)) | uint32(0x1) | blind_coinᵢ )
    450     | uint256(0x0) | uint32(0x0) | uint32(0x0) ))
    451 sig = EdDSA-Sign(reserve.priv, msg)
    452 ]]></artwork>
    453         <artwork><![CDATA[
    454 (E1) coin issuance and signing (exchange)
    455 
    456 denomᵢ = Denom-Lookup(coinᵢ.h_denom)
    457 check denomᵢ.pub known and not withdrawal-expired
    458 check EdDSA-Verify(reserve.pub, msg, sig)
    459 check reserve KYC status ok or not needed
    460 total = sum(~(denomᵢ.value)) + sum(~(denomᵢ.fee_withdraw))
    461 check reserve.balance >= total
    462 reserve.balance -= total
    463 blind_sigᵢ = RSA-FDH-Sign(blind_coinᵢ, denomᵢ.priv)
    464 persist withdrawal
    465 ]]></artwork>
    466         <artwork><![CDATA[
    467 (W4) coin unblinding (wallet)
    468 
    469 coinᵢ.sig = RSA-FDH-Unblind(blind_sigᵢ, blind_secretᵢ, denomᵢ.pub)
    470 check RSA-FDH-Verify(SHA-512(coinᵢ.pub), coinᵢ.sig, denomᵢ.pub)
    471 persist (coinᵢ, blind_secretᵢ)
    472 ]]></artwork>
    473       </section>
    474       <section anchor="payment">
    475         <name>Payment</name>
    476         <t>The wallet obtains <tt>contract</tt> information for an <tt>order</tt> from the merchant
    477 after claiming it with a <tt>nonce</tt>.
    478 Payment of the order is prepared by signing (partial) deposit authorizations (<tt>depositᵢ</tt>) of coins (<tt>coinᵢ</tt>),
    479 where the sum of all contributions (<tt>contributionᵢ &lt;= denomᵢ.value</tt>) must match the <tt>contract.price</tt> plus potential deposit fees.
    480 The payment is complete as soon as the merchant successfully redeems the deposit authorizations at the exchange (cf. <xref target="deposit"/>).</t>
    481         <artwork><![CDATA[
    482             wallet                                  merchant
    483 knows valid coinᵢ                       knows merchant.priv
    484                                         knows exchange, payto
    485                |                                        |
    486                |                      +-----------------------+
    487                |                      | (M1) order generation |
    488                |                      +-----------------------+
    489                |                                        |
    490                |<------- (QR-Code / NFC / URI) ---------|
    491                |          (order.{id,token?})           |
    492                |                                        |
    493 +-----------------------+                               |
    494 | (W1) nonce generation |                               |
    495 +-----------------------+                               |
    496                |                                        |
    497                |------- /orders/{order.id}/claim ------>|
    498                |       (nonce.pub, order.token?)        |
    499                |                                        |
    500                |                      +--------------------------+
    501                |                      | (M2) contract generation |
    502                |                      +--------------------------+
    503                |                                        |
    504                |<---- (contract, merchant.pub, contract_sig) ----|
    505                |                                        |
    506 +--------------------------+                            |
    507 | (W2) payment preparation |                            |
    508 +--------------------------+                            |
    509                |                                        |
    510                |------- /orders/{order.id}/pay -------->|
    511                |              (~deposit)                |
    512                |                                        |
    513                |                      +--------------------+
    514                |                      | (M3) deposit check |
    515                |                      +--------------------+
    516                |                                        |
    517                |<--------------- (sig) -----------------|
    518                |                                        |
    519 +---------------------------+                           |
    520 | (W3) payment verification |                           |
    521 +---------------------------+                           |
    522                |                                        |
    523 ]]></artwork>
    524         <t>where (without age restriction, policy and wallet data hash)</t>
    525         <artwork><![CDATA[
    526 (M1) order generation (merchant)
    527 
    528 wire_salt = random(128)
    529 persist order = (id, price, info, token?, wire_salt)
    530 ]]></artwork>
    531         <artwork><![CDATA[
    532 (W1) nonce generation (wallet)
    533 
    534 nonce = EdDSA-Keygen()
    535 persist nonce.priv
    536 ]]></artwork>
    537         <t>Note that the private key of <tt>nonce</tt> is currently not used anywhere in the protocol.
    538 However, it could be used in the future to prove ownership of an order transaction,
    539 enabling use-cases such as "unclaiming" or transferring an order to another person,
    540 or proving the payment without resorting to the individual coins.</t>
    541         <artwork><![CDATA[
    542 (M2) contract generation (merchant)
    543 
    544 h_wire = HKDF(wire_salt, payto, "merchant-wire-signature", 64)
    545 determine timestamp, refund_deadline, wire_deadline
    546 contract = (order.{id,price,info,token?}, exchange, h_wire, timestamp, refund_deadline, wire_deadline)
    547 check contract.order.token == token
    548 contract.nonce = nonce.pub
    549 persist contract
    550 h_contract = SHA-512(canonicalJSON(contract))
    551 msg = Sign-Msg(MERCHANT_CONTRACT, h_contract)
    552 contract_sig = EdDSA-Sign(merchant.priv, msg)
    553 ]]></artwork>
    554         <artwork><![CDATA[
    555 (W2) payment preparation (wallet)
    556 
    557 h_contract = SHA-512(canonicalJSON(contract))
    558 msg = Sign-Msg(MERCHANT_CONTRACT, h_contract)
    559 check EdDSA-Verify(merchant.pub, msg, contract_sig)
    560 check contract.nonce = nonce
    561 TODO: double-check extra hash check?
    562 ~selection = CoinSelection(contract.{exchange,price}) TODO: include MarkDirty here
    563 (coinᵢ, denomᵢ, contributionᵢ) = selectionᵢ
    564 h_contract = SHA-512(canonicalJSON(contract))
    565 msgᵢ = Sign-Msg(WALLET_COIN_DEPOSIT,
    566     ( h_contract | uint256(0x0)
    567     | uint512(0x0) | contract.h_wire | coinᵢ.h_denom
    568     | contract.timestamp | contract.refund_deadline
    569     | contributionᵢ + denomᵢ.fee_deposit
    570     | denomᵢ.fee_deposit | merchant.pub | uint512(0x0) ))
    571 sigᵢ = EdDSA-Sign(coinᵢ.priv, msgᵢ)
    572 depositᵢ = (coinᵢ.{pub,sig,h_denom}, contributionᵢ, sigᵢ)
    573 persist (contract, ~sig, ~deposit)
    574 ]]></artwork>
    575         <t>// TODO: explain CoinSelection
    576 // TODO: maybe better {sigᵢ} instead of ~sig?
    577 // TODO: maybe introduce symbol for pub/priv
    578 // TODO: maybe rename Sign-Msg as name is currently a bit confusing</t>
    579         <artwork><![CDATA[
    580 (M3) deposit check (merchant)
    581 
    582 check sum(depositᵢ.contribution) == contract.price
    583 check Deposit(~deposit)
    584 msg = Sign-Msg(MERCHANT_PAYMENT_OK, h_contract)
    585 sig = EdDSA-Sign(merchant.priv, msg)
    586 ]]></artwork>
    587         <artwork><![CDATA[
    588 (W3) payment verification (wallet)
    589 
    590 msg = Sign-Msg(MERCHANT_PAYMENT_OK, h_contract)
    591 check EdDSA-Verify(merchant.pub, msg, sig)
    592 ]]></artwork>
    593       </section>
    594       <section anchor="deposit">
    595         <name>Deposit</name>
    596         <t>// todo: add introductory text</t>
    597         <artwork><![CDATA[
    598        merchant/wallet                              exchange
    599 knows exchange.pub                      knows exchange.priv
    600 knows contract_sig                      knows denomᵢ.pub
    601 knows payto, wire_salt                                  |
    602 knows contract, ~deposit                                |
    603                |                                        |
    604 +--------------------------+                            |
    605 | (M1) deposit preparation |                            |
    606 +--------------------------+                            |
    607                |                                        |
    608                |----------- /batch-deposit ------------>|
    609                |    (info, h_contract, ~deposit         |
    610                |     merchant.pub, contract_sig)        |
    611                |                                        |
    612                |                      +-------------------------+
    613                |                      | (E1) deposit validation |
    614                |                      +-------------------------+
    615                |                                        |
    616                |<--- (timestamp, exchange.pub, sig) ----|
    617                |                                        |
    618 +---------------------------+                           |
    619 | (M2) deposit verification |                           |
    620 +---------------------------+                           |
    621                |                                        |
    622 ]]></artwork>
    623         <t>where (without age restriction, policy and wallet data hash)</t>
    624         <artwork><![CDATA[
    625 (M1) Deposit preparation (merchant/wallet)
    626 
    627 h_contract = SHA-512(canonicalJSON(contract))
    628 info.time = contract.{timestamp, wire_deadline, refund_deadline}
    629 info.wire = (payto, wire_salt)
    630 ]]></artwork>
    631         <artwork><![CDATA[
    632 (E1) Deposit validation (exchange)
    633 
    634 coinᵢ = depositᵢ.coin
    635 denomᵢ = Denom-Lookup(coinᵢ.h_denom)
    636 check denomᵢ.pub known and not deposit-expired
    637 h_wire = HKDF(info.wire.wire_salt, info.wire.payto, "merchant-wire-signature", 64)
    638 msgᵢ = Sign-Msg(WALLET_COIN_DEPOSIT,
    639     ( h_contract | uint256(0x0)
    640     | uint512(0x0) | h_wire | coinᵢ.h_denom
    641     | info.time.timestamp | info.time.refund_deadline
    642     | depositᵢ.contribution + denomᵢ.fee_deposit
    643     | denomᵢ.fee_deposit | merchant.pub | uint512(0x0) ))
    644 check EdDSA-Verify(coinᵢ.pub, msgᵢ, depositᵢ.sig)
    645 check RSA-FDH-Verify(SHA-512(coinᵢ.pub), coinᵢ.sig, denomᵢ.pub)
    646 check not overspending
    647 persist deposit-record, mark-spent
    648 schedule bank transfer to payto
    649 timestamp = now()
    650 msg = Sign-Msg(EXCHANGE_CONFIRM_DEPOSIT,
    651     ( h_contract | h_wire | uint512(0x0)
    652     | timestamp | info.time.wire_deadline
    653     | info.time.refund_deadline
    654     | sum(depositᵢ.contribution) - sum(denomᵢ.fee_deposit)
    655     | SHA-512(depositᵢ.sig) | merchant.pub ))
    656 sig = EdDSA-Sign(exchange.priv, msg)
    657 ]]></artwork>
    658         <artwork><![CDATA[
    659 (M2) Deposit verification (merchant/wallet)
    660 
    661 h_wire = HKDF(wire_salt, payto, "merchant-wire-signature", 64)
    662 msg = Sign-Msg(EXCHANGE_CONFIRM_DEPOSIT,
    663     ( h_contract | h_wire | uint512(0x0)
    664     | timestamp | contract.wire_deadline
    665     | contract.refund_deadline
    666     | sum(depositᵢ.contribution) - sum(denomᵢ.fee_deposit)
    667     | SHA-512(depositᵢ.sig) | merchant.pub ))
    668 check EdDSA-Verify(exchange.pub, msg, sig)
    669 ]]></artwork>
    670       </section>
    671       <section anchor="refresh">
    672         <name>Refresh</name>
    673         <t>// todo</t>
    674       </section>
    675       <section anchor="refund">
    676         <name>Refund</name>
    677         <t>// todo</t>
    678       </section>
    679       <section anchor="recoup">
    680         <name>Recoup</name>
    681         <t>// todo</t>
    682       </section>
    683       <section anchor="w2w-push">
    684         <name>Wallet-to-Wallet Push Payment</name>
    685         <t>// todo</t>
    686       </section>
    687       <section anchor="w2w-pull">
    688         <name>Wallet-to-Wallet Pull Payment</name>
    689         <t>// todo</t>
    690       </section>
    691     </section>
    692     <section anchor="security-considerations">
    693       <name>Security Considerations</name>
    694       <t>[ TBD ]</t>
    695     </section>
    696     <section anchor="iana-considerations">
    697       <name>IANA Considerations</name>
    698       <t>None.</t>
    699     </section>
    700   </middle>
    701   <back>
    702     <references anchor="sec-normative-references">
    703       <name>Normative References</name>
    704       <reference anchor="RFC20">
    705         <front>
    706           <title>ASCII format for network interchange</title>
    707           <author fullname="V.G. Cerf" initials="V.G." surname="Cerf"/>
    708           <date month="October" year="1969"/>
    709         </front>
    710         <seriesInfo name="STD" value="80"/>
    711         <seriesInfo name="RFC" value="20"/>
    712         <seriesInfo name="DOI" value="10.17487/RFC0020"/>
    713       </reference>
    714       <reference anchor="RFC2104">
    715         <front>
    716           <title>HMAC: Keyed-Hashing for Message Authentication</title>
    717           <author fullname="H. Krawczyk" initials="H." surname="Krawczyk"/>
    718           <author fullname="M. Bellare" initials="M." surname="Bellare"/>
    719           <author fullname="R. Canetti" initials="R." surname="Canetti"/>
    720           <date month="February" year="1997"/>
    721           <abstract>
    722             <t>This document describes HMAC, a mechanism for message authentication using cryptographic hash functions. HMAC can be used with any iterative cryptographic hash function, e.g., MD5, SHA-1, in combination with a secret shared key. The cryptographic strength of HMAC depends on the properties of the underlying hash function. This memo provides information for the Internet community. This memo does not specify an Internet standard of any kind</t>
    723           </abstract>
    724         </front>
    725         <seriesInfo name="RFC" value="2104"/>
    726         <seriesInfo name="DOI" value="10.17487/RFC2104"/>
    727       </reference>
    728       <reference anchor="RFC5869">
    729         <front>
    730           <title>HMAC-based Extract-and-Expand Key Derivation Function (HKDF)</title>
    731           <author fullname="H. Krawczyk" initials="H." surname="Krawczyk"/>
    732           <author fullname="P. Eronen" initials="P." surname="Eronen"/>
    733           <date month="May" year="2010"/>
    734           <abstract>
    735             <t>This document specifies a simple Hashed Message Authentication Code (HMAC)-based key derivation function (HKDF), which can be used as a building block in various protocols and applications. The key derivation function (KDF) is intended to support a wide range of applications and requirements, and is conservative in its use of cryptographic hash functions. This document is not an Internet Standards Track specification; it is published for informational purposes.</t>
    736           </abstract>
    737         </front>
    738         <seriesInfo name="RFC" value="5869"/>
    739         <seriesInfo name="DOI" value="10.17487/RFC5869"/>
    740       </reference>
    741       <reference anchor="RFC6234">
    742         <front>
    743           <title>US Secure Hash Algorithms (SHA and SHA-based HMAC and HKDF)</title>
    744           <author fullname="D. Eastlake 3rd" initials="D." surname="Eastlake 3rd"/>
    745           <author fullname="T. Hansen" initials="T." surname="Hansen"/>
    746           <date month="May" year="2011"/>
    747           <abstract>
    748             <t>Federal Information Processing Standard, FIPS</t>
    749           </abstract>
    750         </front>
    751         <seriesInfo name="RFC" value="6234"/>
    752         <seriesInfo name="DOI" value="10.17487/RFC6234"/>
    753       </reference>
    754       <reference anchor="HKDF">
    755         <front>
    756           <title>Cryptographic Extraction and Key Derivation: The HKDF Scheme</title>
    757           <author fullname="Hugo Krawczyk" initials="H." surname="Krawczyk">
    758             <organization/>
    759           </author>
    760           <date year="2010"/>
    761         </front>
    762         <seriesInfo name="Lecture Notes in Computer Science" value="pp. 631-648"/>
    763         <seriesInfo name="DOI" value="10.1007/978-3-642-14623-7_34"/>
    764         <seriesInfo name="ISBN" value="[&quot;9783642146220&quot;, &quot;9783642146237&quot;]"/>
    765         <refcontent>Springer Berlin Heidelberg</refcontent>
    766       </reference>
    767       <reference anchor="SHS">
    768         <front>
    769           <title>Secure hash standard</title>
    770           <author>
    771             <organization/>
    772           </author>
    773           <date year="2015"/>
    774         </front>
    775         <seriesInfo name="DOI" value="10.6028/nist.fips.180-4"/>
    776         <refcontent>National Institute of Standards and Technology (U.S.)</refcontent>
    777       </reference>
    778     </references>
    779     <?line 732?>
    780 
    781 <section anchor="change-log">
    782       <name>Change log</name>
    783     </section>
    784     <section numbered="false" anchor="acknowledgments">
    785       <name>Acknowledgments</name>
    786       <t>[ TBD ]</t>
    787       <t>This work was supported in part by the German Federal Ministry of
    788 Education and Research (BMBF) within the project Concrete Contracts.</t>
    789     </section>
    790   </back>
    791   <!-- ##markdown-source:
    792 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
    932 R+AFyWLSsv4XcFI2TK9YAAA=
    933 
    934 -->
    935 
    936 </rfc>