draft-guetschow-taler-protocol.xml (149540B)
1 <?xml version='1.0' encoding='utf-8'?> 2 <!DOCTYPE rfc [ 3 <!ENTITY nbsp " "> 4 <!ENTITY zwsp "​"> 5 <!ENTITY nbhy "‑"> 6 <!ENTITY wj "⁠"> 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="May" day="19"/> 28 <workgroup>independent</workgroup> 29 <keyword>taler</keyword> 30 <keyword>cryptography</keyword> 31 <keyword>ecash</keyword> 32 <keyword>payments</keyword> 33 <abstract> 34 <?line 46?> 35 36 <t>[ TBW ]</t> 37 </abstract> 38 </front> 39 <middle> 40 <?line 50?> 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"/>, without trailing '\0' character.</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>, zero-padded and encoded in network byte order (big endian)</t> 68 </li> 69 <li> 70 <t><tt>uintY(x)</tt> where <tt>Y</tt> is a positive integer number is equivalent to <tt>uint(Y, x)</tt></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 <li> 79 <t><tt>for</tt>, <tt>if</tt>, variable assignment <tt>=</tt>, and conditional operators are to be interpreted like their Python/Julia equivalents</t> 80 </li> 81 <li> 82 <t><tt>data.key</tt> denotes the property <tt>key</tt> on the object <tt>data</tt></t> 83 </li> 84 <li> 85 <t><tt>0..n</tt> denotes the exclusive range of integer numbers from <tt>0</tt> to <tt>n</tt>, i.e., <tt>0, 1, 2, ..., n-1</tt></t> 86 </li> 87 <li> 88 <t><tt>⟨dataᵢ⟩</tt> within a context of <tt>i = 0..n</tt> denotes <tt>n</tt> objects <tt>dataᵢ</tt>, represented in memory as a continuous array</t> 89 </li> 90 <li> 91 <t><tt>⟨dataᵢ.key⟩</tt> within a context of <tt>i = 0..n</tt> denotes an array of the <tt>n</tt> properties <tt>key</tt> of all <tt>n</tt> objects <tt>dataᵢ</tt></t> 92 </li> 93 </ul> 94 </section> 95 <section anchor="cryptographic-primitives"> 96 <name>Cryptographic Primitives</name> 97 <t>// todo: maybe change this description to something more similar to protocol functions (Julia-inspired syntax)</t> 98 <section anchor="cryptographic-hash-functions"> 99 <name>Cryptographic Hash Functions</name> 100 <section anchor="sha256"> 101 <name>SHA-256</name> 102 <artwork><![CDATA[ 103 SHA-256(msg) -> hash 104 105 Input: 106 msg input message of length L < 2^61 octets 107 108 Output: 109 hash message digest of fixed length HashLen = 32 octets 110 ]]></artwork> 111 <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> 112 </section> 113 <section anchor="sha512"> 114 <name>SHA-512</name> 115 <artwork><![CDATA[ 116 SHA-512(msg) -> hash 117 118 Input: 119 msg input message of length L < 2^125 octets 120 121 Output: 122 hash message digest of fixed length HashLen = 64 octets 123 ]]></artwork> 124 <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> 125 </section> 126 <section anchor="sha512-trunc"> 127 <name>SHA-512-256 (truncated SHA-512)</name> 128 <artwork><![CDATA[ 129 SHA-512-256(msg) -> hash 130 131 Input: 132 msg input message of length L < 2^125 octets 133 134 Output: 135 hash message digest of fixed length HashLen = 32 octets 136 ]]></artwork> 137 <t>The output <tt>hash</tt> corresponds to the first 32 octets of the output of SHA-512 defined in <xref target="sha512"/>:</t> 138 <artwork><![CDATA[ 139 temp = SHA-512(msg) 140 hash = temp[0:31] 141 ]]></artwork> 142 <t>Note that this operation differs from SHA-512/256 as defined in <xref target="SHS"/> in the initial hash value.</t> 143 </section> 144 </section> 145 <section anchor="message-authentication-codes"> 146 <name>Message Authentication Codes</name> 147 <section anchor="hmac"> 148 <name>HMAC</name> 149 <artwork><![CDATA[ 150 HMAC-Hash(key, text) -> out 151 152 Option: 153 Hash cryptographic hash function with output length HashLen 154 155 Input: 156 key secret key of length at least HashLen 157 text input data of arbitary length 158 159 Output: 160 out output of length HashLen 161 ]]></artwork> 162 <t><tt>out</tt> is calculated as defined in <xref target="RFC2104"/>.</t> 163 </section> 164 </section> 165 <section anchor="key-derivation-functions"> 166 <name>Key Derivation Functions</name> 167 <section anchor="hkdf"> 168 <name>HKDF</name> 169 <t>The Hashed Key Derivation Function (HKDF) used in Taler is an instantiation of <xref target="RFC5869"/> 170 with two different hash functions for the Extract and Expand step as suggested in <xref target="HKDF"/>: 171 <tt>HKDF-Extract</tt> uses <tt>HMAC-SHA512</tt>, while <tt>HKDF-Expand</tt> uses <tt>HMAC-SHA256</tt> (cf. <xref target="hmac"/>).</t> 172 <artwork><![CDATA[ 173 HKDF(salt, IKM, info, L) -> OKM 174 175 Inputs: 176 salt optional salt value (a non-secret random value); 177 if not provided, it is set to a string of 64 zeros. 178 IKM input keying material 179 info optional context and application specific information 180 (can be a zero-length string) 181 L length of output keying material in octets 182 (<= 255*32 = 8160) 183 184 Output: 185 OKM output keying material (of L octets) 186 ]]></artwork> 187 <t>The output OKM is calculated as follows:</t> 188 <artwork><![CDATA[ 189 PRK = HKDF-Extract(salt, IKM) with Hash = SHA-512 (HashLen = 64) 190 OKM = HKDF-Expand(PRK, info, L) with Hash = SHA-256 (HashLen = 32) 191 ]]></artwork> 192 </section> 193 <section anchor="hkdf-mod"> 194 <name>HKDF-Mod</name> 195 <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> 196 <artwork><![CDATA[ 197 HKDF-Mod(N, salt, IKM, info) -> OKM 198 199 Inputs: 200 N multiple precision integer 201 salt optional salt value (a non-secret random value); 202 if not provided, it is set to a string of 64 zeros. 203 IKM input keying material 204 info optional context and application specific information 205 (can be a zero-length string) 206 207 Output: 208 OKM output keying material (smaller than N) 209 ]]></artwork> 210 <t>The final output <tt>OKM</tt> is determined deterministically based on a counter initialized at zero.</t> 211 <artwork><![CDATA[ 212 counter = 0 213 do until OKM < N: 214 x = HKDF(salt, IKM, info | uint16(counter), bytes(N)) 215 OKM = uint(bits(N), x) 216 counter += 1 217 ]]></artwork> 218 </section> 219 </section> 220 <section anchor="non-blind-signatures"> 221 <name>Non-Blind Signatures</name> 222 <section anchor="ed25519"> 223 <name>Ed25519</name> 224 <t>Taler uses EdDSA instantiated with curve25519 as Ed25519, 225 as defined in Section 5.1 of <xref target="RFC8032"/>. 226 In particular, Taler does <em>not</em> make use of Ed25519ph or Ed25519ctx 227 as defined in that document.</t> 228 <section anchor="key-generation"> 229 <name>Key generation</name> 230 <artwork><![CDATA[ 231 Ed25519-GetPub(priv) -> pub 232 233 Input: 234 priv private Ed25519 key 235 236 Output: 237 pub public Ed25519 key 238 ]]></artwork> 239 <t><tt>pub</tt> is calculated as described in Section 5.1.5 of <xref target="RFC8032"/>.</t> 240 <artwork><![CDATA[ 241 Ed25519-Keygen() -> (priv, pub) 242 243 Output: 244 priv private Ed25519 key 245 pub public Ed25519 key 246 ]]></artwork> 247 <t><tt>priv</tt> and <tt>pub</tt> are calculated as described in Section 5.1.5 of <xref target="RFC8032"/>, 248 which is equivalent to the following:</t> 249 <artwork><![CDATA[ 250 priv = random(256) 251 pub = Ed25519-GetPub(priv) 252 ]]></artwork> 253 </section> 254 <section anchor="signing"> 255 <name>Signing</name> 256 <artwork><![CDATA[ 257 Ed25519-Sign(priv, msg) -> sig 258 259 Inputs: 260 priv Ed25519 private key 261 msg message to be signed 262 263 Output: 264 sig signature on the message by the given private key 265 ]]></artwork> 266 <t><tt>sig</tt> is calculated as described in Section 5.1.6 of <xref target="RFC8032"/>.</t> 267 </section> 268 <section anchor="verifying"> 269 <name>Verifying</name> 270 <artwork><![CDATA[ 271 Ed25519-Verify(pub, msg, sig) -> out 272 273 Inputs: 274 pub Ed25519 public key 275 msg signed message 276 sig signature on msg 277 278 Output: 279 out true, if sig is a valid signature for msg 280 ]]></artwork> 281 <t><tt>out</tt> is the outcome of the last check of Section 5.1.7 of <xref target="RFC8032"/>.</t> 282 </section> 283 </section> 284 </section> 285 <section anchor="key-agreement"> 286 <name>Key Agreement</name> 287 <section anchor="x25519"> 288 <name>X25519</name> 289 <t>Taler uses Elliptic Curve Diffie-Hellman (ECDH) on curve25519 as defined in Section 6.1 of <xref target="RFC7748"/>, 290 but reuses Ed25519 keypairs for one side of the agreement instead of random bytes. 291 Depending on whether the private or public part is from Ed25519, two different functions are used.</t> 292 <artwork><![CDATA[ 293 ECDH-Ed25519-Priv(priv, pub) -> shared 294 295 Input: 296 priv private Ed25519 key 297 pub public X25519 key 298 299 Output: 300 shared shared secret based on the given keys 301 ]]></artwork> 302 <t><tt>shared</tt> is calculated as follows, using the function X25519 defined in Section 5 of <xref target="RFC7748"/>:</t> 303 <artwork><![CDATA[ 304 priv' = SHA-512-256(priv) 305 // todo: missing bit clamping from https://github.com/jedisct1/libsodium/blob/master/src/libsodium/crypto_sign/ed25519/ref10/keypair.c#L71 306 shared' = X25519(priv', pub) 307 shared = SHA-512(shared') 308 ]]></artwork> 309 <artwork><![CDATA[ 310 ECDH-Ed25519-Pub(priv, pub) -> shared 311 312 Input: 313 priv private X25519 key 314 pub public Ed25519 key 315 316 Output: 317 shared shared secret based on the given keys 318 ]]></artwork> 319 <t><tt>shared</tt> is calculated as follows, using the function X25519 defined in Section 5 of <xref target="RFC7748"/>, 320 and <tt>Convert-Point-Ed25519-Curve25519(p)</tt> which implements the birational map of Section 4.1 of <xref target="RFC7748"/>:</t> 321 <artwork><![CDATA[ 322 pub' = Convert-Point-Ed25519-Curve25519(pub) 323 shared' = X25519(priv, pub') 324 shared = SHA-512(shared') 325 ]]></artwork> 326 <artwork><![CDATA[ 327 ECDH-GetPub(priv) -> pub 328 329 Input: 330 priv private X25519 key 331 332 Output: 333 pub public X25519 key 334 ]]></artwork> 335 <t><tt>pub</tt> is calculated according to Section 6.1 of <xref target="RFC7748"/>:</t> 336 <artwork><![CDATA[ 337 pub = X25519(priv, 9) 338 ]]></artwork> 339 </section> 340 </section> 341 <section anchor="blind-signatures"> 342 <name>Blind Signatures</name> 343 <section anchor="rsa-fdh"> 344 <name>RSA-FDH</name> 345 <section anchor="supporting-functions"> 346 <name>Supporting Functions</name> 347 <artwork><![CDATA[ 348 RSA-FDH(msg, pubkey) -> fdh 349 350 Inputs: 351 msg message 352 pubkey RSA public key consisting of modulus N and public exponent e 353 354 Output: 355 fdh full-domain hash of msg over pubkey.N 356 ]]></artwork> 357 <t><tt>fdh</tt> is calculated based on HKDF-Mod from <xref target="hkdf-mod"/> as follows:</t> 358 <artwork><![CDATA[ 359 info = "RSA-FDA FTpsW!" 360 salt = uint16(bytes(pubkey.N)) | uint16(bytes(pubkey.e)) 361 | pubkey.N | pubkey.e 362 fdh = HKDF-Mod(pubkey.N, salt, msg, info) 363 ]]></artwork> 364 <t>The resulting <tt>fdh</tt> can be used to test against a malicious RSA pubkey 365 by verifying that the greatest common denominator (gcd) of <tt>fdh</tt> and <tt>pubkey.N</tt> is 1.</t> 366 <artwork><![CDATA[ 367 RSA-FDH-Derive(bks, pubkey) -> out 368 369 Inputs: 370 bks blinding key secret of length L = 32 octets 371 pubkey RSA public key consisting of modulus N and public exponent e 372 373 Output: 374 out full-domain hash of bks over pubkey.N 375 ]]></artwork> 376 <t><tt>out</tt> is calculated based on HKDF-Mod from <xref target="hkdf-mod"/> as follows:</t> 377 <artwork><![CDATA[ 378 info = "Blinding KDF" 379 salt = "Blinding KDF extractor HMAC key" 380 fdh = HKDF-Mod(pubkey.N, salt, bks, info) 381 ]]></artwork> 382 </section> 383 <section anchor="blinding"> 384 <name>Blinding</name> 385 <artwork><![CDATA[ 386 RSA-FDH-Blind(msg, bks, pubkey) -> out 387 388 Inputs: 389 msg message 390 bks blinding key secret of length L = 32 octets 391 pubkey RSA public key consisting of modulus N and public exponent e 392 393 Output: 394 out message blinded for pubkey 395 ]]></artwork> 396 <t><tt>out</tt> is calculated based on RSA-FDH from <xref target="rsa-fdh"/> as follows:</t> 397 <artwork><![CDATA[ 398 data = RSA-FDH(msg, pubkey) 399 r = RSA-FDH-Derive(bks, pubkey) 400 r_e = r ** pubkey.e (mod pubkey.N) 401 out = r_e * data (mod pubkey.N) 402 ]]></artwork> 403 </section> 404 <section anchor="signing-1"> 405 <name>Signing</name> 406 <artwork><![CDATA[ 407 RSA-FDH-Sign(data, privkey) -> sig 408 409 Inputs: 410 data data to be signed, an integer smaller than privkey.N 411 privkey RSA private key consisting of modulus N and private exponent d 412 413 Output: 414 sig signature on data by privkey 415 ]]></artwork> 416 <t><tt>sig</tt> is calculated as follows:</t> 417 <artwork><![CDATA[ 418 sig = data ** privkey.d (mod privkey.N) 419 ]]></artwork> 420 </section> 421 <section anchor="unblinding"> 422 <name>Unblinding</name> 423 <artwork><![CDATA[ 424 RSA-FDH-Unblind(sig, bks, pubkey) -> out 425 426 Inputs: 427 sig blind signature 428 bks blinding key secret of length L = 32 octets 429 pubkey RSA public key consisting of modulus N and public exponent e 430 431 Output: 432 out unblinded signature 433 ]]></artwork> 434 <t><tt>out</tt> is calculated as follows:</t> 435 <artwork><![CDATA[ 436 r = RSA-FDH-Derive(bks, pubkey) 437 r_inv = inverse of r (mod pubkey.N) 438 out = sig * r_inv (mod pubkey.N) 439 ]]></artwork> 440 </section> 441 <section anchor="verifying-1"> 442 <name>Verifying</name> 443 <artwork><![CDATA[ 444 RSA-FDH-Verify(msg, sig, pubkey) -> out 445 446 Inputs: 447 msg message 448 sig signature of pubkey over msg 449 pubkey RSA public key consisting of modulus N and public exponent e 450 451 Output: 452 out true, if sig is a valid signature 453 ]]></artwork> 454 <t><tt>out</tt> is calculated based on RSA-FDH from <xref target="rsa-fdh"/> as follows:</t> 455 <artwork><![CDATA[ 456 data = RSA-FDH(msg, pubkey) 457 exp = sig ** pubkey.e (mod pubkey.N) 458 out = (data == exp) 459 ]]></artwork> 460 </section> 461 </section> 462 <section anchor="cbs"> 463 <name>Clause-Schnorr</name> 464 </section> 465 </section> 466 </section> 467 <section anchor="datatypes-and-notation"> 468 <name>Datatypes and Notation</name> 469 <section anchor="amounts"> 470 <name>Amounts</name> 471 <t>Amounts are represented in Taler as positive fixed-point values 472 consisting of <tt>value</tt> as the non-negative integer part of the base currency, 473 the <tt>fraction</tt> given in units of one hundred millionth (1e-8) of the base currency, 474 and <tt>currency</tt> as the 3-11 ASCII characters identifying the currency.</t> 475 <t>Whenever used in the protocol, the binary representation of an <tt>amount</tt> is 476 <tt>uint64(amount.value) | uint32(amount.fraction) | padZero(12, amount.currency)</tt>.</t> 477 </section> 478 <section anchor="timestamps"> 479 <name>Timestamps</name> 480 <t>Absolute timestamps are represented as <tt>uint64(x)</tt> where <tt>x</tt> corresponds to 481 the microseconds since <tt>1970-01-01 00:00 CEST</tt> (the UNIX epoch). 482 The special value <tt>0xFFFFFFFFFFFFFFFF</tt> represents "never". 483 <!-- 484 // todo: check if needed and correct 485 Relative timestamps are represented as `uint64(x)` where `x` is given in microseconds. 486 The special value `0xFFFFFFFFFFFFFFFF` represents "forever". 487 --> 488 </t> 489 </section> 490 <section anchor="signatures"> 491 <name>Signatures</name> 492 <t>All messages to be signed in Taler start with a header containing their total size 493 (including the header) and a fixed signing context (purpose) as registered by GANA in the 494 <eref target="https://gana.gnunet.org/gnunet-signatures/gnunet_signatures.html">GNUnet Signature Purposes</eref> 495 registry. Taler-specific purposes start at 1000.</t> 496 <artwork><![CDATA[ 497 Gen-Msg(purpose, msg) -> out 498 499 Inputs: 500 purpose signature purpose as registered at GANA 501 msg message content (excl. header) to be signed 502 503 Output: 504 out complete message (incl. header) to be signed 505 ]]></artwork> 506 <t><tt>out</tt> is formed as follows:</t> 507 <artwork><![CDATA[ 508 out = uint32(len(msg) + 8) | uint32(purpose) | msg 509 ]]></artwork> 510 </section> 511 <section anchor="helper-functions"> 512 <name>Helper Functions</name> 513 <t>There are a certain number of single-argument functions which are often needed, 514 and therefore omit the parentheses of the typical function syntax:</t> 515 <ul spacing="normal"> 516 <li> 517 <t><tt>Knows data</tt> specifies <tt>data</tt> that is known a priori at the start of the protocol operation</t> 518 </li> 519 <li> 520 <t><tt>Determine data</tt> specifies <tt>data</tt> that is determined according to the business logic and current state of the protocol entity</t> 521 </li> 522 <li> 523 <t><tt>Check cond</tt> verifies that the boolean condition or variable <tt>cond</tt> is true, 524 or aborts the protocol operation otherwise</t> 525 </li> 526 <li> 527 <t><tt>Persist data</tt> persists the given <tt>data</tt> to the local database</t> 528 </li> 529 <li> 530 <t><tt>data = Lookup by key</tt> retrieves previously persisted <tt>data</tt> by the given <tt>key</tt></t> 531 </li> 532 <li> 533 <t><tt>Sum ⟨dataᵢ⟩</tt> is valid for numerical objects <tt>dataᵢ</tt> including amounts (cf. <xref target="amounts"/>), 534 and denotes the numerical sum of these objects</t> 535 </li> 536 </ul> 537 <t>Some more functions that are commonly used throughout <xref target="protocol"/>:</t> 538 <artwork><![CDATA[ 539 Hash-Denom(denom) = 540 SHA-512(uint32(0) | uint32(1) | denom.pub) 541 542 Hash-Planchet(planchet, denom) = 543 SHA-512( SHA-512( denom.pub ) | uint32(0x1) | planchet ) 544 545 Hash-Contract(contract) = 546 SHA-512( canonicalJSON(contract) | 0x0) 547 548 Check-Subtract(value, subtrahend) = 549 Check value >= subtrahend 550 Persist value -= subtrahend 551 ]]></artwork> 552 <t><tt>canonicalJSON(data)</tt> canonicalizes <tt>data</tt> represented as JSON 553 according to the JSON Canonicalization Scheme (JCS) defined in <xref target="RFC8785"/>. 554 Note that <tt>data</tt> as input to <tt>canonicalJSON</tt> is restricted as follows for Taler:</t> 555 <ul spacing="normal"> 556 <li> 557 <t>For JSON Object member names, only strings matching the regular expression <tt>^[0-9A-Z_a-z]+$</tt> or the literal names <tt>$forgettable</tt> or <tt>$forgotten</tt> are allowed. 558 This makes the sorting of object members easier, as <xref target="RFC8785"/> requires sorting by UTF-16 code points.</t> 559 </li> 560 <li> 561 <t>Floating point numbers are forbidden. Numbers must be integers in the range <tt>-(2**53 - 1)</tt> to <tt>(2**52) - 1</tt>.</t> 562 </li> 563 </ul> 564 </section> 565 </section> 566 <section anchor="protocol"> 567 <name>The Taler Crypto Protocol</name> 568 <t>The Taler payment protocol is a token-based <em>e-cash</em> system 569 which ensures anonymity for payers (much like physical cash), 570 while guaranteing income transparency on the payees' side (much like most digital payment systems). 571 Contrary to what the name might suggest, 572 Taler neither is a separate currency (as cryptocurrencies do) 573 nor is it tied to a specific currency. 574 Instead, the payment system operator offering the Taler payment protocol 575 can freely choose the assets backing the payment system.</t> 576 <t>The basic system consists of three types of entities:</t> 577 <ol spacing="normal" type="1"><li> 578 <t>The Taler <em>exchange</em> is run by the payment system operator. 579 It is the central, trusted entity which hands out e-cash and holds the corresponding value.</t> 580 </li> 581 <li> 582 <t>A Taler <em>wallet</em> manages e-cash in self-custody for end users.</t> 583 </li> 584 <li> 585 <t>A Taler <em>merchant</em> can redeem e-cash at the exchange 586 after the wallet authorized a deposit permission during a payment.</t> 587 </li> 588 </ol> 589 <t>E-cash in Taler is represented as digital tokens called <em>coins</em>. 590 They are public-private keypairs where ownership of the coin 591 is equivalent to the knowledge of the private key <tt>coin.priv</tt>. 592 Every coin has an initial value corresponding to a denomination (<tt>denom</tt>) offered by the exchange. 593 The validity of coins is signaled by the presence of 594 a valid denomination signature <tt>coin.sig</tt> on the (hash of the) public key <tt>coin.pub</tt>. 595 To ensure payer anonymity, the exchange generates <tt>coin.sig</tt> without learning the actual (hash of) <tt>coin.pub</tt> 596 using a <em>blind</em> signature scheme.</t> 597 <t>Wallets obtain coins from the exchange during <em>withdrawal</em> (cf. <xref target="withdraw"/>) 598 and use them during <em>payment</em> at merchants, who in turn <em>deposit</em> them at the exchange (cf. <xref target="payment"/>). 599 Residual value on partly spent coins can be <em>refreshed</em> by the wallet subsequently in order to obtain unlinkable change (cf. <xref target="refresh"/>). 600 Taler also supports receiving e-cash in a wallet without acting as a merchant using <em>wallet-to-wallet payments</em> (W2W, cf. <xref target="w2w"/>), 601 which are always handled via the exchange.</t> 602 <t>Honest operation of the exchange can be optionally supervised by an independant third-party Taler <em>auditor</em>. 603 This supervision is not part of the basic Taler protocol and thus not part of this document.</t> 604 <artwork><![CDATA[ 605 - exchange - 606 / \ 607 Withdrawal / \ Deposit 608 Refresh / W2W \ 609 / \ 610 wallet ----------- merchant 611 Payment 612 ]]></artwork> 613 <t>// todo: capitalize wallet, exchange, merchant everywhere?</t> 614 <t>In the default configuration, Taler uses RSA-FDH (cf. <xref target="rsa-fdh"/>) for (blind) denomination signatures 615 and Ed25519 (cf. <xref target="ed25519"/>) signatures everywhere else. 616 Clause-Schnorr Signatures (cf. <xref target="cbs"/>) provide an alternative blind signature scheme operating on Elliptic Curves. 617 As their usage is still experimental, they are not described as part of this document.</t> 618 <t>Taler has optional support for age-restricted coins, enabling privacy-preserving age restriction. 619 As an optional feature, it is not part of the basic Taler protocol and thus left out of the description in this document.</t> 620 <section anchor="obtaining-e-cash"> 621 <name>Obtaining E-Cash</name> 622 <section anchor="withdraw"> 623 <name>Withdrawal</name> 624 <t>The wallet generates <tt>n > 0</tt> coins <tt>⟨coinᵢ⟩</tt> and requests <tt>n</tt> signatures <tt>⟨blind_sigᵢ⟩</tt> from the exchange, 625 attributing value to the coins according to <tt>n</tt> chosen denominations <tt>⟨denomᵢ⟩</tt>. 626 The total value and withdrawal fee (defined by the exchange per denomination) 627 must be smaller or equal to the amount stored in the single reserve used for withdrawal.</t> 628 <t>// todo: document TALER_MAX_COINS = 64 per operation (due to CS-encoding)</t> 629 <t>// todo: extend with extra roundtrip for CBS</t> 630 <artwork><![CDATA[ 631 wallet exchange 632 Knows ⟨denomᵢ⟩ Knows ⟨denomᵢ.priv⟩ 633 | | 634 +-----------------------------+ | 635 | (W1) reserve key generation | | 636 +-----------------------------+ | 637 | | 638 |----------- (bank transfer) ----------->| 639 | (subject: reserve.pub, amount: value) | 640 | | 641 | +------------------------------+ 642 | | Persist (reserve.pub, value) | 643 | +------------------------------+ 644 | | 645 +-----------------------------------+ | 646 | (W2) coin generation and blinding | | 647 +-----------------------------------+ | 648 | | 649 |-------------- /withdraw -------------->| 650 | (reserve.pub, planchets, sig) | 651 | | 652 | +--------------------------------+ 653 | | (E1) coin issuance and signing | 654 | +--------------------------------+ 655 | | 656 |<---------- (⟨blind_sigᵢ⟩) -------------| 657 | | 658 +----------------------+ | 659 | (W3) coin unblinding | | 660 +----------------------+ | 661 | | 662 ]]></artwork> 663 <t>where (for RSA, without age-restriction)</t> 664 <sourcecode type="pseudocode"><![CDATA[ 665 (W1) reserve key generation (wallet) 666 667 reserve = Ed25519-Keygen() 668 Persist (reserve, value) 669 ]]></sourcecode> 670 <t>The wallet derives coins and blinding secrets using a HKDF from a single seed per withdrawal operation, 671 together with an integer index. 672 This is strictly speaking an implementation detail since the seed is never revealed to any other party, 673 and might be chosen to be implemented differently.</t> 674 <sourcecode type="pseudocode"><![CDATA[ 675 (W2) coin generation and blinding (wallet) 676 677 batch_seed = random(256) 678 Persist batch_seed 679 for i in 0..n: 680 coin_seedᵢ = HKDF(uint32(i), batch_seed, "taler-withdrawal-coin-derivation", 64) 681 blind_secretᵢ = coin_seedᵢ[32:] 682 coinᵢ.priv = coin_seedᵢ[:32] 683 coinᵢ.pub = Ed25519-GetPub(coinᵢ.priv) 684 h_denomᵢ = Hash-Denom(denomᵢ) 685 planchetᵢ = RSA-FDH-Blind(SHA-512(coinᵢ.pub), blind_secretᵢ, denomᵢ.pub) 686 h_planchetᵢ = Hash-Planchet(planchetᵢ, denomᵢ) 687 planchets = (⟨h_denomᵢ⟩, ⟨planchetᵢ⟩) 688 msg = Gen-Msg(WALLET_RESERVE_WITHDRAW, 689 ( Sum ⟨denomᵢ.value⟩ | Sum ⟨denomᵢ.fee_withdraw⟩ 690 | SHA-512( ⟨h_planchetᵢ⟩ ) | uint256(0x0) | uint32(0x0) | uint32(0x0) )) 691 sig = Ed25519-Sign(reserve.priv, msg) 692 693 // todo: exchange.git uses different derivation than wallet-core.git (above): 694 ⟨coin_seedᵢ⟩ = HKDF(uint32(n), batch_seed, "taler-withdraw-secrets", 32*n) 695 for i in 0..n: 696 blind_secretᵢ = HKDF("bks", coin_seedᵢ, "", 32) 697 coinᵢ.priv = HKDF("coin", coin_seedᵢ, "", 32) 698 ]]></sourcecode> 699 <sourcecode type="pseudocode"><![CDATA[ 700 (E1) coin issuance and signing (exchange) 701 702 (⟨h_denomᵢ⟩, ⟨planchetᵢ⟩) = planchets 703 for i in 0..n: 704 denomᵢ = Lookup by h_denomᵢ 705 Check denomᵢ known and not withdraw-expired 706 h_planchetᵢ = Hash-Planchet(planchetᵢ, denomᵢ) 707 msg = Gen-Msg(WALLET_RESERVE_WITHDRAW, 708 ( Sum ⟨denomᵢ.value⟩ | Sum ⟨denomᵢ.fee_withdraw⟩ 709 | SHA-512( ⟨h_planchetᵢ⟩ ) | uint256(0x0) | uint32(0x0) | uint32(0x0) )) 710 Check Ed25519-Verify(reserve.pub, msg, sig) 711 Check reserve KYC status ok or not needed 712 total = Sum ⟨denomᵢ.value⟩ + Sum ⟨denomᵢ.fee_withdraw⟩ 713 Check-Subtract(reserve.balance, total) 714 for i in 0..n: 715 blind_sigᵢ = RSA-FDH-Sign(planchetᵢ, denomᵢ.priv) 716 Persist withdrawal // todo: what exactly? should be checked first for replay? 717 ]]></sourcecode> 718 <sourcecode type="pseudocode"><![CDATA[ 719 (W3) coin unblinding (wallet) 720 721 for i in 0..n: 722 coinᵢ.sig = RSA-FDH-Unblind(blind_sigᵢ, blind_secretᵢ, denomᵢ.pub) 723 Check RSA-FDH-Verify(SHA-512(coinᵢ.pub), coinᵢ.sig, denomᵢ.pub) 724 coinᵢ.value = denomᵢ.value 725 coinᵢ.h_denom = h_denomᵢ 726 coinᵢ.blind_secret = blind_secretᵢ // todo: why save blind_secret, if batch_seed already persisted? 727 Persist ⟨coinᵢ⟩ 728 ]]></sourcecode> 729 </section> 730 <section anchor="withdraw-recoup"> 731 <name>Recoup</name> 732 <t>// todo</t> 733 </section> 734 </section> 735 <section anchor="payment-with-e-cash"> 736 <name>Payment with E-Cash</name> 737 <section anchor="payment"> 738 <name>Payment and Deposit</name> 739 <t>The wallet obtains <tt>contract</tt> information for an <tt>order</tt> from the merchant 740 after claiming it with a <tt>nonce</tt>. 741 Payment of the order is prepared by signing (partial) deposit authorizations <tt>⟨depositᵢ⟩</tt> with coins <tt>⟨coinᵢ⟩</tt> of certain denominations <tt>⟨denomᵢ⟩</tt>, 742 where the sum of all contributions (<tt>contributionᵢ + denomᵢ.fee_deposit <= denomᵢ.value</tt>) 743 must match the <tt>contract.price</tt> plus potential deposit fees <tt>⟨denomᵢ.fee_deposit⟩</tt>. 744 The payment is complete as soon as the merchant successfully redeems the deposit authorizations at the exchange.</t> 745 <t>Deposit could also be used directly by a wallet with its own payto and a minimal contract.</t> 746 <t>// todo: should we integrate payment templates here?</t> 747 <artwork><![CDATA[ 748 wallet merchant exchange 749 Knows ⟨coinᵢ⟩ Knows merchant.priv Knows exchange.priv 750 | Knows exchange, payto Knows ⟨denomᵢ⟩ 751 | | | 752 | +-----------------------+ | 753 | | (M1) order generation | | 754 | +-----------------------+ | 755 | | | 756 |<--- (QR-Code / NFC / URI) ---| | 757 | (order.{id,token?}) | | 758 | | | 759 +-----------------------+ | | 760 | (W1) nonce generation | | | 761 +-----------------------+ | | 762 | | | 763 |-- /orders/{order.id}/claim ->| | 764 | (nonce.pub, order.token?) | | 765 | | | 766 | +--------------------------+ | 767 | | (M2) contract generation | | 768 | +--------------------------+ | 769 | | | 770 |<-- (contract, merchant.pub, -| | 771 | sig) | | 772 | | | 773 +--------------------------+ | | 774 | (W2) payment preparation | | | 775 +--------------------------+ | | 776 | | | 777 |--- /orders/{order.id}/pay -->| | 778 | (⟨depositᵢ⟩) | | 779 | | | 780 | +--------------------------+ | 781 | | (M3) deposit preparation | | 782 | +--------------------------+ | 783 | | | 784 | |-------- /batch-deposit ----->| 785 | | (info, h_contract, ⟨depositᵢ⟩| 786 | | merchant.pub, sig) | 787 | | | 788 | | +--------------------+ 789 | | | (E1) deposit check | 790 | | +--------------------+ 791 | | | 792 | |<------ (time_deposit, -------| 793 | | exchange.pub, sig) | 794 | | | 795 | +---------------------------+ | 796 | | (M4) deposit verification | | 797 | +---------------------------+ | 798 | | | 799 |<----------- (sig) -----------| | 800 | | | 801 +---------------------------+ | | 802 | (W3) payment verification | | | 803 +---------------------------+ | | 804 | | | 805 ]]></artwork> 806 <t>where (without age restriction, policy and wallet data hash)</t> 807 <sourcecode type="pseudocode"><![CDATA[ 808 (M1) order generation (merchant) 809 810 wire_salt = random(128) 811 Determine price, and ASCII strings id, info, token? 812 Persist order = (id, price, info, token?, wire_salt) 813 ]]></sourcecode> 814 <sourcecode type="pseudocode"><![CDATA[ 815 (W1) nonce generation (wallet) 816 817 nonce = Ed25519-Keygen() 818 Persist nonce.priv 819 ]]></sourcecode> 820 <t>Note that the private key of <tt>nonce</tt> is currently not used anywhere in the protocol. 821 However, it could be used in the future to prove ownership of an order transaction, 822 enabling use-cases such as "unclaiming" or transferring an order to another person, 823 or proving the payment without resorting to the individual coins.</t> 824 <sourcecode type="pseudocode"><![CDATA[ 825 (M2) contract generation (merchant) 826 827 Check order.token? == token? 828 h_wire = HKDF(wire_salt, payto, "merchant-wire-signature", 64) 829 timestamp = now() 830 Determine refund_deadline, wire_deadline from timestamp 831 Determine max_fees from price 832 contract = (order.{id,price,info,token?}, exchange, h_wire, timestamp, refund_deadline, wire_deadline, max_fees) 833 contract.nonce = nonce.pub 834 Persist contract 835 h_contract = Hash-Contract(contract) 836 msg = Gen-Msg(MERCHANT_CONTRACT, h_contract) 837 sig = Ed25519-Sign(merchant.priv, msg) 838 ]]></sourcecode> 839 <sourcecode type="pseudocode"><![CDATA[ 840 (W2) payment preparation (wallet) 841 842 h_contract = Hash-Contract(contract) 843 msg = Gen-Msg(MERCHANT_CONTRACT, h_contract) 844 Check Ed25519-Verify(merchant.pub, msg, sig) 845 Check contract.nonce == nonce 846 // TODO: double-check extra hash check? 847 for i in 0..n: 848 Determine coinᵢ, denomᵢ, contribution_netᵢ for contract.{exchange,price,max_fees} 849 contribution_grossᵢ = contribution_netᵢ + denomᵢ.fee_deposit 850 Check-Subtract(coinᵢ.value, contribution_grossᵢ) 851 msgᵢ = Gen-Msg(WALLET_COIN_DEPOSIT, 852 ( h_contract | uint256(0x0) 853 | uint512(0x0) | contract.h_wire | coinᵢ.h_denom 854 | timestamp | contract.refund_deadline 855 | contribution_grossᵢ | denomᵢ.fee_deposit 856 | merchant.pub | uint512(0x0) )) 857 sigᵢ = Ed25519-Sign(coinᵢ.priv, msgᵢ) 858 depositᵢ = (coinᵢ.{pub,sig,h_denom}, contribution_grossᵢ, sigᵢ) 859 Persist (contract, ⟨sigᵢ⟩, ⟨depositᵢ⟩) 860 ]]></sourcecode> 861 <sourcecode type="pseudocode"><![CDATA[ 862 (M3) deposit preparation (merchant) 863 864 for i in 0..n: 865 denomᵢ = Lookup by depositᵢ.coin.h_denom 866 contribution_netᵢ = depositᵢ.contribution_gross - denomᵢ.fee_deposit 867 Check Sum ⟨contribution_netᵢ⟩ >= contract.price - contract.max_fees 868 info.time = contract.{timestamp, wire_deadline, refund_deadline} 869 info.wire = (payto, wire_salt) 870 h_contract = Hash-Contract(contract) 871 msg = Gen-Msg(MERCHANT_CONTRACT, h_contract) 872 sig = Ed25519-Sign(merchant.priv, msg) 873 ]]></sourcecode> 874 <t>TODO: what about wire_fees, those should be checked for as well, or do we just assume merchant will pay those? 875 see src/backend/taler-merchant-httpd_post-orders-ORDER_ID-pay.c:2760</t> 876 <sourcecode type="pseudocode"><![CDATA[ 877 (E1) deposit check (exchange) 878 879 h_wire = HKDF(info.wire.wire_salt, info.wire.payto, "merchant-wire-signature", 64) 880 for i in 0..n: 881 coinᵢ = depositᵢ.coin 882 denomᵢ = Lookup by coinᵢ.h_denom 883 Check denomᵢ known and not deposit-expired 884 msgᵢ = Gen-Msg(WALLET_COIN_DEPOSIT, 885 ( h_contract | uint256(0x0) 886 | uint512(0x0) | h_wire | coinᵢ.h_denom 887 | info.time.timestamp | info.time.refund_deadline 888 | depositᵢ.contribution_gross | denomᵢ.fee_deposit 889 | merchant.pub | uint512(0x0) )) 890 Check Ed25519-Verify(coinᵢ.pub, msgᵢ, depositᵢ.sig) 891 Check RSA-FDH-Verify(SHA-512(coinᵢ.pub), coinᵢ.sig, denomᵢ.pub) 892 Check-Subtract(coinᵢ.value, depositᵢ.contribution_gross) 893 Persist deposit-record 894 schedule bank transfer to payto 895 time_deposit = now() 896 msg = Gen-Msg(EXCHANGE_CONFIRM_DEPOSIT, 897 ( h_contract | h_wire | uint512(0x0) 898 | time_deposit | info.time.wire_deadline 899 | info.time.refund_deadline 900 | Sum ⟨depositᵢ.contribution_gross⟩ 901 | SHA-512( ⟨depositᵢ.sig⟩ ) | merchant.pub )) 902 sig = Ed25519-Sign(exchange.priv, msg) 903 ]]></sourcecode> 904 <sourcecode type="pseudocode"><![CDATA[ 905 (M2) deposit verification (merchant) 906 907 h_wire = HKDF(wire_salt, payto, "merchant-wire-signature", 64) 908 msg = Gen-Msg(EXCHANGE_CONFIRM_DEPOSIT, 909 ( h_contract | h_wire | uint512(0x0) 910 | time_deposit | contract.wire_deadline 911 | contract.refund_deadline 912 | Sum ⟨depositᵢ.contribution⟩ 913 | SHA-512( ⟨depositᵢ.sig⟩ ) | merchant.pub )) 914 Check Ed25519-Verify(exchange.pub, msg, sig) 915 msg = Gen-Msg(MERCHANT_PAYMENT_OK, h_contract) 916 sig = Ed25519-Sign(merchant.priv, msg) 917 ]]></sourcecode> 918 <sourcecode type="pseudocode"><![CDATA[ 919 (W3) payment verification (wallet) 920 921 msg = Gen-Msg(MERCHANT_PAYMENT_OK, h_contract) 922 Check Ed25519-Verify(merchant.pub, msg, sig) 923 ]]></sourcecode> 924 </section> 925 <section anchor="refund"> 926 <name>Refund</name> 927 <t>A wallet can request a refund for an order from the merchant after it has been completed successfully 928 (cf. <xref target="payment"/>) and before the merchant has been paid out by the exchange (i.e., before <tt>contract.wire_deadline</tt>). 929 The merchant needs to approve the refund via its business logic, 930 and is free to decide the total amount of the refund 931 as well as which coins' deposit operations are (potentially partly) invalidated. 932 After the exchange has accepted the refund request, 933 the coins obtain their (partial) value back. 934 The wallet should proceed to refresh (cf. <xref target="refresh"/>) the coins before spending them again 935 to obtain unlinkability.</t> 936 <t>In case the wallet itself has used deposit to its own payto, 937 it can act as the merchant in the protocol below.</t> 938 <artwork><![CDATA[ 939 wallet merchant exchange 940 Knows order.id Knows merchant.priv Knows deposit_record 941 Knows contract | for coinᵢ.pub 942 | | | 943 +---------------------+ | | 944 | (W1) refund request | | | 945 +---------------------+ | | 946 | | | 947 |- /orders/{order.id}/refund ->| | 948 | (h_contract) | | 949 | | | 950 | +------------------------+ | 951 | | (M1) refund processing | | 952 | +------------------------+ | 953 | | | 954 | |- /coins/{coinᵢ.pub}/refund ->| 955 | | (valueᵢ, h_contract, id, | 956 | | merchant.pub, sigᵢ) | 957 | | | 958 | | +-------------------+ 959 | | | (E1) refund check | 960 | | +-------------------+ 961 | | | 962 | |<--- (exchange.pub, sigᵢ) ----| 963 | | | 964 | +--------------------------+ | 965 | | (M2) refund confirmation | | 966 | +--------------------------+ | 967 | | | 968 |<-----(value, ⟨refundᵢ⟩,------| | 969 | merchant.pub) | | // todo: why merchant.pub if no sig transmitted? 970 | | | 971 +-----------------------+ | | 972 | (W2) refund reception | | | 973 +-----------------------+ | | 974 | | | 975 ]]></artwork> 976 <t>where (for RSA, without age-restriction)</t> 977 <sourcecode type="pseudocode"><![CDATA[ 978 (W1) refund request (wallet) 979 980 h_contract = Hash-Contract(contract) 981 ]]></sourcecode> 982 <sourcecode type="pseudocode"><![CDATA[ 983 (M1) refund processing (merchant) 984 985 Check h_contract known and refund possible 986 time = now() 987 ⟨coinᵢ⟩ = Lookup by h_contract 988 id = uint32(random(32)) 989 for i in 0..n: 990 denomᵢ = Lookup by coinᵢ.h_denom 991 valueᵢ = refund amount // todo: split wisely 992 msgᵢ = Gen-Msg(MERCHANT_REFUND, 993 ( h_contract | coinᵢ.pub | id | valueᵢ | denomᵢ.fee_refund )) 994 sigᵢ = Ed25519-Sign(merchant.priv, msgᵢ) 995 ]]></sourcecode> 996 <sourcecode type="pseudocode"><![CDATA[ 997 (E1) refund check and confirmation (exchange) 998 999 deposit_record = Lookup by h_contract // todo: needs to be persisted before with order.id and used coins! 1000 Check refund possible (prior to wire transfer deadline) 1001 for i in 0..n: 1002 Check coinᵢ.pub part of deposit_record 1003 denomᵢ = Lookup by coinᵢ.pub 1004 msgᵢ = Gen-Msg(MERCHANT_REFUND, 1005 ( h_contract | coinᵢ.pub | id | valueᵢ | denomᵢ.fee_refund )) 1006 Check Ed25519-Verify(merchant.pub, msgᵢ, sigᵢ) 1007 Check valueᵢ >= denomᵢ.fee_refund 1008 remove/update scheduled wire transfer 1009 Persist coinᵢ.value += valueᵢ - denomᵢ.fee_refund 1010 msgᵢ = Gen-Msg(MERCHANT_REFUND_OK, SHA-512(order.id)) 1011 sigᵢ = Ed25519-Sign(exchange.priv, msgᵢ) 1012 ]]></sourcecode> 1013 <sourcecode type="pseudocode"><![CDATA[ 1014 (M2) refund confirmation (merchant) 1015 1016 for i in 0..n: 1017 msgᵢ = Gen-Msg(MERCHANT_REFUND_OK, SHA-512(order.id)) 1018 Check Ed25519-Verify(exchange.pub, msgᵢ, sigᵢ) 1019 update business logic 1020 refundᵢ = (valueᵢ, sigᵢ, id, coinᵢ.pub, time) 1021 value = sum ⟨valueᵢ⟩ 1022 ]]></sourcecode> 1023 <sourcecode type="pseudocode"><![CDATA[ 1024 (W2) refund reception (wallet) 1025 1026 for i in 0..n: 1027 (valueᵢ, sigᵢ, id, coinᵢ.pub, time) = refundᵢ 1028 update persistent transaction information 1029 refresh ⟨coinᵢ⟩ 1030 ]]></sourcecode> 1031 </section> 1032 </section> 1033 <section anchor="obtaining-unlinkable-change"> 1034 <name>Obtaining unlinkable change</name> 1035 <section anchor="refresh"> 1036 <name>Refresh</name> 1037 <t>The wallet obtains <tt>n</tt> new coins <tt>⟨coinᵢ⟩</tt> of denominations <tt>⟨denomᵢ⟩</tt> 1038 in exchange for one old <tt>coin</tt> of denomination <tt>denom</tt> from the exchange. 1039 There are three reasons why a wallet needs to do this:</t> 1040 <ol spacing="normal" type="1"><li> 1041 <t>Obtaining unlinkable change after using only a part of the coin's value during a payment (cf. <xref target="payment"/>), 1042 i.e., where <tt>coin.value < denom.value</tt></t> 1043 </li> 1044 <li> 1045 <t>Obtaining unlinkable change after a successful refund (cf. <xref target="refund"/>)</t> 1046 </li> 1047 <li> 1048 <t>Renewing a coin before it deposit-expires</t> 1049 </li> 1050 </ol> 1051 <t>The sum of the refresh fee of <tt>denom</tt> and the new denominations' values and withdrawal fees (defined by the exchange) 1052 must be smaller or equal to the residual value of the old coin (<tt>coin.value</tt>).</t> 1053 <t>The private key of each new coin candidate <tt>⟨coinₖᵢ.priv⟩</tt> is transitively derived from the old coin's private key <tt>coin.priv</tt> 1054 via a 512-bit secret <tt>⟨sharedₖᵢ⟩</tt> according to <tt>Refresh-Derive</tt>. 1055 The secret is regeneratable with the knowledge of <tt>coin.priv</tt> via the link protocol (cf. <xref target="link"/>). 1056 The derivation ensures that ownership of coins (knowledge of the private key) is correctly transferred, 1057 and thereby that value transfer among untrusted parties can only happen via payment and deposit, not via refresh.</t> 1058 <artwork><![CDATA[ 1059 Refresh-Derive(shared, i, denom) = 1060 planchet_seed = HKDF(uint32(i), shared, "taler-coin-derivation", 64) 1061 blind_secret = HKDF("bks", planchet_seed, "", 32) 1062 coin.priv = HKDF("coin", planchet_seed, "", 32) 1063 coin.pub = Ed25519-GetPub(coin.priv) 1064 planchet = RSA-FDH-Blind(SHA-512(coin.pub), blind_secret, denom.pub) 1065 h_planchet = Hash-Planchet(planchet, denom) 1066 return (coin, blind_secret, planchet, h_planchet) 1067 ]]></artwork> 1068 <t>Taler uses a cut-and-choose protocol with the fixed parameter <tt>κ=3</tt> to enforce correct derivation 1069 of <tt>⟨sharedₖᵢ⟩</tt> from a single seed per batch of planchets <tt>⟨batch_seedₖ⟩</tt> 1070 (in (κ-1)/κ of the cases, making income concealment for tax evasion purposes unpractical).</t> 1071 <t>Refreshing consists of two parts:</t> 1072 <ol spacing="normal" type="1"><li> 1073 <t>Melting of the old coin and commiting to κ batches of blinded planchet candidates</t> 1074 </li> 1075 <li> 1076 <t>Revelation of κ-1 secrets <tt>⟨revealed_seedₖ⟩</tt> to prove the proper construction of the (revealed) batches of blinded planchet candidates.</t> 1077 </li> 1078 </ol> 1079 <artwork><![CDATA[ 1080 wallet exchange 1081 Knows ⟨denomᵢ⟩ Knows ⟨denomᵢ.priv⟩ 1082 Knows coin | 1083 | | 1084 +-------------------+ | 1085 | (W1) coin melting | | 1086 +-------------------+ | 1087 | | 1088 |---------------- /melt ---------------->| 1089 | (coin.{pub,sig,h_denom}, value, | 1090 | refresh_seed, planchets, sig) | 1091 | | 1092 | +---------------------------------------+ 1093 | | (E1) gamma selection and coin signing | 1094 | +---------------------------------------+ 1095 | | 1096 |<------ (ɣ, exchange.pub, sig) ---------| 1097 | | 1098 +------------------------+ | 1099 | (W2) secret revelation | | 1100 +------------------------+ | 1101 | | 1102 |------------ /reveal-melt ------------->| 1103 | (commitment, ⟨revealed_seedₖ⟩) | 1104 | | 1105 | +----------------------------+ 1106 | | (E2) commitment validation | 1107 | +----------------------------+ 1108 | | 1109 |<---------- (⟨blind_sigᵢ⟩) -------------| 1110 | | 1111 +----------------------+ | 1112 | (W3) coin unblinding | | 1113 +----------------------+ | 1114 | | 1115 ]]></artwork> 1116 <t>where (for RSA, without age-restriction)</t> 1117 <sourcecode type="pseudocode"><![CDATA[ 1118 (W1) coin melting (wallet) 1119 1120 refresh_seed = random(256) 1121 ⟨batch_seedₖ⟩ = HKDF("refresh-batch-seeds", refresh_seed, coin.priv, k*64) 1122 for k in 0..κ: 1123 ⟨transferₖᵢ.priv⟩ = HKDF("refresh-transfer-private-keys", batch_seedₖ, "", n*32) 1124 for i in 0..n: 1125 transferₖᵢ.pub = ECDH-GetPub(transferₖᵢ.priv) 1126 sharedₖᵢ = ECDH-Ed25519-Pub(transferₖᵢ.priv, coin.pub) 1127 (coinₖᵢ, blind_secretₖᵢ, planchetₖᵢ, h_planchetₖᵢ) = Refresh-Derive(sharedₖᵢ, denomᵢ) 1128 h_planchetsₖ = SHA-512( ⟨h_planchetₖᵢ⟩ ) 1129 value = coin.denom.fee_refresh + Sum ⟨denomᵢ.value⟩ + Sum ⟨denomᵢ.fee_withdraw⟩ 1130 commitment = SHA-512( refresh_seed | uint256(0x0) | coin.pub | value 1131 | SHA-512( ⟨h_planchetsₖ⟩ ) ) 1132 for i in 0..n: 1133 h_denomᵢ = Hash-Denom(denomᵢ) 1134 planchets = (⟨h_denomᵢ⟩, ⟨planchetₖᵢ⟩, ⟨transferₖᵢ.pub⟩)) 1135 msg = Gen-Msg(WALLET_COIN_MELT, 1136 ( commitment | coin.h_denom | uint256(0x0) 1137 | value | denom.fee_refresh )) 1138 sig = Ed25519-Sign(coin.priv, msg) 1139 Persist (coin.denom.pub, ...) // todo: double-check 1140 ]]></sourcecode> 1141 <sourcecode type="pseudocode"><![CDATA[ 1142 (E1) gamma selection and coin signing (exchange) 1143 1144 denom = Lookup by coin.h_denom 1145 Check denom known and not deposit-expired 1146 Check RSA-FDH-Verify(SHA-512(coin.pub), coin.sig, denom.pub) 1147 Check coin.pub known and dirty 1148 (⟨h_denomᵢ⟩, ⟨planchetₖᵢ⟩, ⟨transferₖᵢ.pub⟩)) = planchets 1149 for i in 0..n: 1150 denomᵢ = Lookup by h_denomᵢ 1151 Check denomᵢ known and not withdraw-expired 1152 value' = coin.denom.fee_refresh + Sum ⟨denomᵢ.value⟩ + Sum ⟨denomᵢ.fee_withdraw⟩ 1153 Check value' == value 1154 Check-Subtract(coin.value, value) 1155 for k in 0..κ: 1156 for i in 0..n: 1157 h_planchetₖᵢ = Hash-Planchet(planchetₖᵢ, denomᵢ) 1158 h_planchetsₖ = SHA-512( ⟨h_planchetₖᵢ⟩ ) 1159 commitment = SHA-512( refresh_seed | uint256(0x0) | coin.pub | value 1160 | SHA-512( ⟨h_planchetsₖ⟩ ) ) 1161 msg = Gen-Msg(WALLET_COIN_MELT, 1162 ( commitment | coin.h_denom | uint256(0x0) 1163 | value | denom.fee_refresh )) 1164 Check Ed25519-Verify(coin.pub, msg, sig) 1165 refresh_record = Lookup by commitment 1166 (ɣ, _, _, done, _) = refresh_record 1167 if refresh_record not found: 1168 ɣ = 0..κ at random 1169 for i in 0..n: 1170 blind_sigᵢ = RSA-FDH-Sign(planchetᵧᵢ, denomᵧᵢ.priv) 1171 link_info = (refresh_seed, ⟨transferₖᵢ.pub⟩, ⟨h_denomᵢ⟩, coin_sig) 1172 Persist refresh_record = (commitment, ɣ, ⟨blind_sigᵢ⟩, h_planchetsᵧ, false, link_info) 1173 msg = Gen-Msg(EXCHANGE_CONFIRM_MELT, 1174 ( commitment | uint32(ɣ) )) 1175 sig = Ed25519-Sign(exchange.priv, msg) 1176 ]]></sourcecode> 1177 <sourcecode type="pseudocode"><![CDATA[ 1178 (W2) secret revelation (wallet) 1179 1180 Check exchange.pub known 1181 msg = Gen-Msg(EXCHANGE_CONFIRM_MELT, 1182 ( commitment | uint32(ɣ) )) 1183 Check Ed25519-Verify(exchange.pub, msg, sig) 1184 Persist refresh-challenge // what exactly? 1185 for k in 0..κ and k != ɣ: 1186 revealed_seedₖ = batch_seedₖ 1187 ]]></sourcecode> 1188 <sourcecode type="pseudocode"><![CDATA[ 1189 (E2) commitment validation (exchange) 1190 1191 refresh_record = Lookup by commitment 1192 (ɣ, ⟨blind_sigᵢ⟩, h_planchetsᵧ, done, _) = refresh_record 1193 Check not done // todo: sure? 1194 for k in 0..κ and k != ɣ: 1195 ⟨transferₖᵢ.priv⟩ = HKDF("refresh-transfer-private-keys", batch_seedₖ, "", n*32) 1196 for i in 0..n: 1197 transferₖᵢ.pub = ECDH-GetPub(transferₖᵢ.priv) 1198 sharedₖᵢ = ECDH-Ed25519-Pub(transferₖᵢ.priv, coin.pub) 1199 (_, _, _, h_planchetₖᵢ) = Refresh-Derive(sharedₖᵢ, denomᵢ) 1200 h_planchetsₖ = SHA-512( ⟨h_planchetₖᵢ⟩ ) 1201 value = coin.denom.fee_refresh + Sum ⟨denomᵢ.value⟩ + Sum ⟨denomᵢ.fee_withdraw⟩ 1202 commitment' = SHA-512( refresh_seed | uint256(0x0) | coin.pub | value 1203 | SHA-512( ⟨h_planchetsₖ⟩ ) ) 1204 Check commitment == commitment' 1205 Persist refresh_record = (_, _, _, true, _) 1206 ]]></sourcecode> 1207 <sourcecode type="pseudocode"><![CDATA[ 1208 (W3) coin unblinding (wallet) 1209 1210 for i in 0..n: 1211 coinᵧᵢ.sig = RSA-FDH-Unblind(blind_sigᵧᵢ, blind_secretᵧᵢ, denomᵢ.pub) 1212 Check RSA-FDH-Verify(SHA-512(coinᵧᵢ.pub), coinᵧᵢ.sig, denomᵢ.pub) 1213 coinᵧᵢ.h_denom = h_denomᵢ 1214 Persist ⟨coinᵧᵢ⟩ 1215 ]]></sourcecode> 1216 </section> 1217 <section anchor="link"> 1218 <name>Link</name> 1219 <t>Coins ⟨coinᵧᵢ⟩ obtained via the refresh protocol (cf. <xref target="refresh"/>) can be regenerated 1220 with the knowledge of the old coin's private key <tt>coin.priv</tt> using the link protocol, 1221 integrated in the coin history endpoint.</t> 1222 <artwork><![CDATA[ 1223 wallet exchange 1224 Knows coin Knows refresh_record for coin.pub 1225 | | 1226 +----------------------+ | 1227 | (W1) history request | | 1228 +----------------------+ | 1229 | | 1230 |------ /coins/{coin.pub}/history ------>| 1231 | (sig) | 1232 | | 1233 | +----------------------------+ 1234 | | (E1) refresh secret lookup | 1235 | +----------------------------+ 1236 | | 1237 |<------------- (melt_info) -------------| 1238 | | 1239 +-----------------------+ | 1240 | (W2) coin acquisition | | 1241 +-----------------------+ | 1242 | | 1243 ]]></artwork> 1244 <t>where (for RSA, without age-restriction)</t> 1245 <sourcecode type="pseudocode"><![CDATA[ 1246 (W1) history request (wallet) 1247 1248 msg = Gen-Msg(COIN_HISTORY_REQUEST, uint64(0x0)) 1249 sig = Ed25519-Sign(coin.priv, msg) 1250 ]]></sourcecode> 1251 <sourcecode type="pseudocode"><![CDATA[ 1252 (E1) refresh secret lookup (exchange) 1253 1254 refresh_record = Lookup by coin.pub 1255 (ɣ, ⟨blind_sigᵢ⟩, _, done, link_info) = refresh_record 1256 if done: 1257 melt_info = (ɣ, link_info, ⟨blind_sigᵢ⟩) 1258 else: 1259 melt_info = (ɣ, link_info) 1260 ]]></sourcecode> 1261 <sourcecode type="pseudocode"><![CDATA[ 1262 (W2) coin acquisition (wallet) 1263 1264 (ɣ, link_info, ⟨blind_sigᵢ⟩?) = melt_info 1265 (refresh_seed, ⟨transferₖᵢ.pub⟩, ⟨h_denomᵢ⟩, coin_sig) = link_info 1266 1267 for i in 0..n: 1268 denomᵢ = Lookup by h_denomᵢ 1269 for k in 0..κ: 1270 for i in 0..n: 1271 sharedₖᵢ = ECDH-Ed25519-Priv(coin.priv, transferₖᵢ.pub) 1272 (coinₖᵢ, blind_secretₖᵢ _, h_planchetₖᵢ) = Refresh-Derive(sharedₖᵢ, denomᵢ) 1273 h_planchetsₖ = SHA-512( ⟨h_planchetₖᵢ⟩ ) 1274 value = coin.denom.fee_refresh + Sum ⟨denomᵢ.value⟩ + Sum ⟨denomᵢ.fee_withdraw⟩ 1275 commitment = SHA-512( refresh_seed | uint256(0x0) | coin.pub | value 1276 | SHA-512( ⟨h_planchetsₖ⟩ ) ) 1277 msg = Gen-Msg(WALLET_COIN_MELT, 1278 ( commitment | coin.h_denom | uint256(0x0) 1279 | value | denom.fee_refresh )) 1280 Check Ed25519-Verify(coin.pub, msg, sig) 1281 1282 if ⟨blind_sigᵢ⟩ returned: 1283 for i in 0..n: 1284 coinᵧᵢ.sig = RSA-FDH-Unblind(blind_sigᵧᵢ, blind_secretᵧᵢ, denomᵢ.pub) 1285 Check RSA-FDH-Verify(SHA-512(coinᵧᵢ.pub), coinᵧᵢ.sig, denomᵢ.pub) 1286 coinᵧᵢ.h_denom = h_denomᵢ 1287 Persist ⟨coinᵧᵢ⟩ 1288 ]]></sourcecode> 1289 </section> 1290 <section anchor="refresh-recoup"> 1291 <name>Recoup</name> 1292 <t>// todo</t> 1293 </section> 1294 </section> 1295 <section anchor="w2w"> 1296 <name>Transfer of E-Cash</name> 1297 <t>// todo: introductory text</t> 1298 <t>Transactions in E-Cash between wallets. 1299 Commonly referred to as peer-to-peer transactions. 1300 In Taler, interaction with exchange, therefore called wallet-to-wallet transactions.</t> 1301 <section anchor="w2w-account"> 1302 <name>Account Creation</name> 1303 </section> 1304 <section anchor="w2w-push"> 1305 <name>Push Payment</name> 1306 <t>// todo</t> 1307 </section> 1308 <section anchor="w2w-pull"> 1309 <name>Pull Payment</name> 1310 <t>// todo</t> 1311 </section> 1312 </section> 1313 </section> 1314 <section anchor="security-considerations"> 1315 <name>Security Considerations</name> 1316 <t>[ TBD ]</t> 1317 </section> 1318 <section anchor="iana-considerations"> 1319 <name>IANA Considerations</name> 1320 <t>None.</t> 1321 </section> 1322 </middle> 1323 <back> 1324 <references anchor="sec-normative-references"> 1325 <name>Normative References</name> 1326 <reference anchor="RFC20"> 1327 <front> 1328 <title>ASCII format for network interchange</title> 1329 <author fullname="V.G. Cerf" initials="V.G." surname="Cerf"/> 1330 <date month="October" year="1969"/> 1331 </front> 1332 <seriesInfo name="STD" value="80"/> 1333 <seriesInfo name="RFC" value="20"/> 1334 <seriesInfo name="DOI" value="10.17487/RFC0020"/> 1335 </reference> 1336 <reference anchor="RFC2104"> 1337 <front> 1338 <title>HMAC: Keyed-Hashing for Message Authentication</title> 1339 <author fullname="H. Krawczyk" initials="H." surname="Krawczyk"/> 1340 <author fullname="M. Bellare" initials="M." surname="Bellare"/> 1341 <author fullname="R. Canetti" initials="R." surname="Canetti"/> 1342 <date month="February" year="1997"/> 1343 <abstract> 1344 <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> 1345 </abstract> 1346 </front> 1347 <seriesInfo name="RFC" value="2104"/> 1348 <seriesInfo name="DOI" value="10.17487/RFC2104"/> 1349 </reference> 1350 <reference anchor="RFC5869"> 1351 <front> 1352 <title>HMAC-based Extract-and-Expand Key Derivation Function (HKDF)</title> 1353 <author fullname="H. Krawczyk" initials="H." surname="Krawczyk"/> 1354 <author fullname="P. Eronen" initials="P." surname="Eronen"/> 1355 <date month="May" year="2010"/> 1356 <abstract> 1357 <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> 1358 </abstract> 1359 </front> 1360 <seriesInfo name="RFC" value="5869"/> 1361 <seriesInfo name="DOI" value="10.17487/RFC5869"/> 1362 </reference> 1363 <reference anchor="RFC6234"> 1364 <front> 1365 <title>US Secure Hash Algorithms (SHA and SHA-based HMAC and HKDF)</title> 1366 <author fullname="D. Eastlake 3rd" initials="D." surname="Eastlake 3rd"/> 1367 <author fullname="T. Hansen" initials="T." surname="Hansen"/> 1368 <date month="May" year="2011"/> 1369 <abstract> 1370 <t>Federal Information Processing Standard, FIPS</t> 1371 </abstract> 1372 </front> 1373 <seriesInfo name="RFC" value="6234"/> 1374 <seriesInfo name="DOI" value="10.17487/RFC6234"/> 1375 </reference> 1376 <reference anchor="RFC7748"> 1377 <front> 1378 <title>Elliptic Curves for Security</title> 1379 <author fullname="A. Langley" initials="A." surname="Langley"/> 1380 <author fullname="M. Hamburg" initials="M." surname="Hamburg"/> 1381 <author fullname="S. Turner" initials="S." surname="Turner"/> 1382 <date month="January" year="2016"/> 1383 <abstract> 1384 <t>This memo specifies two elliptic curves over prime fields that offer a high level of practical security in cryptographic applications, including Transport Layer Security (TLS). These curves are intended to operate at the ~128-bit and ~224-bit security level, respectively, and are generated deterministically based on a list of required properties.</t> 1385 </abstract> 1386 </front> 1387 <seriesInfo name="RFC" value="7748"/> 1388 <seriesInfo name="DOI" value="10.17487/RFC7748"/> 1389 </reference> 1390 <reference anchor="RFC8032"> 1391 <front> 1392 <title>Edwards-Curve Digital Signature Algorithm (EdDSA)</title> 1393 <author fullname="S. Josefsson" initials="S." surname="Josefsson"/> 1394 <author fullname="I. Liusvaara" initials="I." surname="Liusvaara"/> 1395 <date month="January" year="2017"/> 1396 <abstract> 1397 <t>This document describes elliptic curve signature scheme Edwards-curve Digital Signature Algorithm (EdDSA). The algorithm is instantiated with recommended parameters for the edwards25519 and edwards448 curves. An example implementation and test vectors are provided.</t> 1398 </abstract> 1399 </front> 1400 <seriesInfo name="RFC" value="8032"/> 1401 <seriesInfo name="DOI" value="10.17487/RFC8032"/> 1402 </reference> 1403 <reference anchor="RFC8785"> 1404 <front> 1405 <title>JSON Canonicalization Scheme (JCS)</title> 1406 <author fullname="A. Rundgren" initials="A." surname="Rundgren"/> 1407 <author fullname="B. Jordan" initials="B." surname="Jordan"/> 1408 <author fullname="S. Erdtman" initials="S." surname="Erdtman"/> 1409 <date month="June" year="2020"/> 1410 <abstract> 1411 <t>Cryptographic operations like hashing and signing need the data to be expressed in an invariant format so that the operations are reliably repeatable. One way to address this is to create a canonical representation of the data. Canonicalization also permits data to be exchanged in its original form on the "wire" while cryptographic operations performed on the canonicalized counterpart of the data in the producer and consumer endpoints generate consistent results.</t> 1412 <t>This document describes the JSON Canonicalization Scheme (JCS). This specification defines how to create a canonical representation of JSON data by building on the strict serialization methods for JSON primitives defined by ECMAScript, constraining JSON data to the Internet JSON (I-JSON) subset, and by using deterministic property sorting.</t> 1413 </abstract> 1414 </front> 1415 <seriesInfo name="RFC" value="8785"/> 1416 <seriesInfo name="DOI" value="10.17487/RFC8785"/> 1417 </reference> 1418 <reference anchor="HKDF"> 1419 <front> 1420 <title>Cryptographic Extraction and Key Derivation: The HKDF Scheme</title> 1421 <author fullname="Hugo Krawczyk" initials="H." surname="Krawczyk"> 1422 <organization/> 1423 </author> 1424 <date year="2010"/> 1425 </front> 1426 <seriesInfo name="Lecture Notes in Computer Science" value="pp. 631-648"/> 1427 <seriesInfo name="DOI" value="10.1007/978-3-642-14623-7_34"/> 1428 <seriesInfo name="ISBN" value="["9783642146220", "9783642146237"]"/> 1429 <refcontent>Springer Berlin Heidelberg</refcontent> 1430 </reference> 1431 <reference anchor="SHS"> 1432 <front> 1433 <title>Secure hash standard</title> 1434 <author> 1435 <organization/> 1436 </author> 1437 <date year="2015"/> 1438 </front> 1439 <seriesInfo name="DOI" value="10.6028/nist.fips.180-4"/> 1440 <refcontent>National Institute of Standards and Technology (U.S.)</refcontent> 1441 </reference> 1442 </references> 1443 <?line 1460?> 1444 1445 <section anchor="test-vectors"> 1446 <name>Test Vectors</name> 1447 <t>This appendix provides two sets of test vectors for testing Taler Protocol implementations. 1448 They are generated by going through the protocol operations in the following order:</t> 1449 <ol spacing="normal" type="1"><li> 1450 <t>Withdraw two coins <tt>coin₀</tt> and <tt>coin₁</tt> from a single <tt>reserve</tt> (cf. <xref target="withdraw"/>).</t> 1451 </li> 1452 <li> 1453 <t>Pay for one <tt>order</tt> with the full value of <tt>coin₀</tt> and a partial value of <tt>coin₁</tt> (cf. <xref target="payment"/>).</t> 1454 </li> 1455 <li> 1456 <t>Obtain a partial refund on <tt>coin₀</tt> used to pay for the <tt>order</tt> (cf. <xref target="refund"/>).</t> 1457 </li> 1458 <li> 1459 <t>Refresh the now-dirty <tt>coin₁</tt> to two new coins <tt>coin₂</tt> and <tt>coin₃</tt> (cf. <xref target="refresh"/>).</t> 1460 </li> 1461 <li> 1462 <t>Regenerate <tt>coin₂</tt> and <tt>coin₃</tt> with the knowledge of <tt>coin₁</tt> (cf. <xref target="link"/>).</t> 1463 </li> 1464 <li> 1465 <t>Create an <tt>account</tt> for w2w transfers (cf. <xref target="w2w-account"/>).</t> 1466 </li> 1467 <li> 1468 <t>Send a payment to <tt>account</tt> with the full value of <tt>coin₂</tt>, obtaining <tt>coin₄</tt> (cf. <xref target="w2w-push"/>).</t> 1469 </li> 1470 <li> 1471 <t>Request a payment to <tt>account</tt>, which is paid with the full value of <tt>coin₄</tt>, obtaining <tt>coin₅</tt> (cf. <xref target="w2w-pull"/>).</t> 1472 </li> 1473 <li> 1474 <t>Recoup the value of <tt>coin₅</tt> obtained via withdrawal from <tt>account</tt> (cf. <xref target="withdraw-recoup"/>).</t> 1475 </li> 1476 <li> 1477 <t>Recoup the value of <tt>coin₃</tt> obtained via refresh from <tt>coin₁</tt> (cf. <xref target="refresh-recoup"/>).</t> 1478 </li> 1479 </ol> 1480 <t>// todo: p2p sending full coins only works without fees, should we set fees to zero?</t> 1481 <t>// todo: refund would be slightly more interesting with 2 coins being (partially) refunded, 1482 should we change to full refund coin0 + partial refund coin1 (coin1 value after fee_deposit + fee_refund should then match denom2 + denom3)</t> 1483 <t>The test vectors in this document have been generated by the GNU Taler reference implementation written in C. 1484 All binary data is provided in hexadecimal notation. 1485 Big numbers for RSA are represented in big-endian byte order (most significant byte first).</t> 1486 <section anchor="test-case-1"> 1487 <name>Test Case 1</name> 1488 <sourcecode type="pseudocode"><![CDATA[ 1489 exchange.master_pub = 3cb5e9823db2b335fdb3f284ae960e56be8b081c6819b8 1490 b0217f38b095b4313b 1491 exchange.priv = 1bf4149fa644b3c7f2bf02da4703ff2de3fa160dce0c75 1492 0eabfa0f7ac70a2442 1493 exchange.pub = 4c130aae3246831808a162e2d4330de394e5f0d7dff75a 1494 80f3fa045b1a43eabb 1495 exchange.url = https://exchange.taler.example.org/ 1496 denom₀.pub.n = ba42b9e75e48847bab175ed4797384d68a430fd849a914 1497 aa68438349743b2728d9ca97709c15d5c81c7d9d11c84e 1498 c9c60cec03aed4b36ad153768eb30cf9845474e97ee9d7 1499 475ebc926d87135d56926b7df1cea3ec38897a74bc3e24 1500 5e59ffa76e5aff2c2f2eb84e7133a879f4229221f91c7b 1501 ddf96088e4020e16444d94acc30708069f4a1bde3dcbea 1502 d32e3916a9f6722adb3d63bb9075dde49258fbd28a9a09 1503 251fa08b64faee53a506b9f637136c72af7382b9243fa8 1504 996ad4d72cc1b05cfb45271cb3187b4eeec0b5f9e847cd 1505 cc0c3ddef9787164a1aee7e4e1ee6de1b95282c1ff646a 1506 a70aabd1df0003f75d3585e9e740916cee4f7bca0cd82f 1507 72104d 1508 denom₀.pub.e = 010001 1509 denom₀.priv.d = 07bc432fbc6eeb0f9ec2a4f5d2886d65228f57ee5ddac7 1510 88af355493bd9fc247d449b161e41d95080f44d93bd693 1511 8d162c4db5f6720f7479768ba73000f330df780e856e8d 1512 3a01d1778c546e85b3157820de24bc9290238782271a36 1513 94f38c6645f3420331ff70f8930377f4fea25beaccc775 1514 ce796f9ca7c97d0fc82ce7a6880dd437e6b30695ca51a5 1515 8f0239aef7481932550ce61b5b085313cb888c893cc1bb 1516 ef6b47c607e1189f8cccb04eeb9f87b9e53f414850f8b9 1517 23ce83e2859c0434a3d14d861e864fd5ce701af1161139 1518 8a73515b7056b2828e564cdec6052bdbb43ff435178577 1519 198de0676e5d378ade9b31844e81e2218ba3b3aec5bff9 1520 a26621 1521 denom₀.value = KUDOS:5.12 1522 denom₀.fee_withdraw = KUDOS:0.01 1523 denom₀.fee_deposit = KUDOS:0.01 1524 denom₀.fee_refresh = KUDOS:0.01 1525 denom₀.fee_refund = KUDOS:0.01 1526 denom₁.pub.n = d5455fb79449df7bf548e384d5201d75f4f7697ef9b805 1527 1eb8536f66783e70ca2d524fefa6840c1f87d9d8814868 1528 15d5ace866a32269b05bdba7ff6024811c19456026b0a5 1529 9da4db96f58729d286c90be8cd9cbf575d346202b43282 1530 d601b5751ff77a88a0742a692349a0e3fa8ed5518fc537 1531 8fcf434929b541c942573abef310b87776e976e81cf650 1532 a04399fabddbde677163918250c4d45f5e90ee7539de50 1533 0a8e915be1d5f17d79cb9585ccdf5dba42ef53c24eae7d 1534 7c93c4e0a432788245b7c76a587f0ac6889d3038953136 1535 2d51c2ad65cb1e28b4ad4cc97fcd2a4aedd6612ae8888e 1536 b2dbc4de0cf30f46a43b76cc8c3245eefe013195a237f0 1537 2d13b5 1538 denom₁.pub.e = 010001 1539 denom₁.priv.d = 5a520e0e663bbeecf55d5015d258ce8145247ec62aa5d7 1540 6d422cfbb1cedccad1a4ce06527d17d1368d47221ce678 1541 463eff02516d6746914ce5c2c9318364366d31675e1b53 1542 9866d8249f89059a4640e0cd503ec0fe13d7fa6620c07f 1543 8e789ccba4a51f7cbb4f5722bdb211f45b09a0a7f11659 1544 c88ac37939b3accfba4bccf24ea260e21aaec0dfbf8571 1545 78438986e963e9e356277c3badc34fc91b705d9956b4be 1546 dc0947d65924d7dd31e564de798eb06837380caed6813d 1547 3761d119901c5540eb74c3cb674fdfd64b67d78ebd40de 1548 0cafd53c038a0a8e87890b953b8b94a9771a6efb3142ca 1549 02db873053f8d1de2082db4366fc072aafc723c036a2fb 1550 999605 1551 denom₁.value = KUDOS:2.56 1552 denom₁.fee_withdraw = KUDOS:0.01 1553 denom₁.fee_deposit = KUDOS:0.01 1554 denom₁.fee_refresh = KUDOS:0.01 1555 denom₁.fee_refund = KUDOS:0.01 1556 denom₂.pub.n = d1320993658042f995f09ed66ad2283e457a1f44cad96f 1557 1cf5a6299ac93d61724a7448d70e56a38666ec66352a58 1558 10ca3e544d957dedb5789e135589fcb8b139c65a2f70d7 1559 c421dfd4e27cf38d463074d286730be23d446fc0781151 1560 9b068346b28b86b94acff35524eb62436852714c92f03b 1561 0bac21bb6bf727734be7871b702f928c3ced4bad9ba2d4 1562 9cec6a86d1019181c65c16abf7b391f103c90c3eaaaa9d 1563 5298a4a60c71bdaf0f08246327a62399bf4c424c1ed771 1564 8cb5df178daa9710ec9d098e99ed0456de2fbaf7865ba4 1565 7931c52d1cac78cacc1bc451782587487a6189addfe5dc 1566 df6f190f28816707e3d1e104b5a1f7a570b75c1951588f 1567 3289ef 1568 denom₂.pub.e = 010001 1569 denom₂.priv.d = 311849a8066faa083218b4e6444e8af44650e94ab7427d 1570 31b232eb5bb0b3cf8d478cefd54cbfa783f0deb503f02a 1571 97d226fb98f3a708a508a82c886c285bddf7dda5a7b197 1572 69a7bb84961cd5f9c749b2f8ff65bb99be6033cbdb41d1 1573 418d2f3ce5c519fa9d649d4a53ae4c32dea64e81b6905b 1574 831b44155cbab5cef8b6defde09295662cdf2189f2763e 1575 de05bea0acb707b9b6b087dcebb9ca81f1c2785d6560f9 1576 3bf1a1860676cccceb079c22b48b9fdef68e1d286164f1 1577 32ffddeab29fa7a704e1bc3f9f5e28c39675f17136aed8 1578 542aa4470a14a7380a4016b21d43ef5b9e2b241ced017c 1579 54247c12fd6beccb7bd356820b0246553c751b3e071468 1580 c2efdd 1581 denom₂.value = KUDOS:0.16 1582 denom₂.fee_withdraw = KUDOS:0.01 1583 denom₂.fee_deposit = KUDOS:0.01 1584 denom₂.fee_refresh = KUDOS:0.01 1585 denom₂.fee_refund = KUDOS:0.01 1586 denom₃.pub.n = bddb1806b7b7663d94bedbeccbb515987fcae457b5920d 1587 85b8485edac6ab0e73e6991780e9f1fa6f88e500e0ccd9 1588 eeb80d8e3b66289a7cf1b25bd56d05081d583864ad225a 1589 36f8d38391782a85bfe320d439443e8ea19f555edb36fc 1590 b58af81ca5168ca7c42dda68f191bd1587b4da27703384 1591 f2aad300a043549c67fc6defd98bd1074b3bab1bc0d89b 1592 87d81f8a1f555a3b4ce2b4ca7b0b1d8f446fa93258db51 1593 1cc3bc2ff62871cb4c746f6806d0b839db8cc560da06eb 1594 5619d9d42309a77161373708db18e453ff0a1d6f63281c 1595 54ffacada7c8bf5ca7281ffe7e2e5be03fc006c064d820 1596 f719e672429628837399a565dd9d70f6e9ed91e1eb0567 1597 978015 1598 denom₃.pub.e = 010001 1599 denom₃.priv.d = 1e3370867d0a0d1705b18e0d848d73f7d422f920e4aec2 1600 3cea7184b9463a26c1e9704d4cacaa5952b8683eb403e7 1601 8a5c628cfa1b9da0e44d9462f1b7f66c1c883b419f484e 1602 d3de257e113c1828e4e5e3592f1a3bddf78d7f88927ee9 1603 9892c3362ca2c226dbd90971d68a54404d069d5f5704b3 1604 04e131fb3058959338781a203993804f64def2980210dc 1605 3f4e77c1207400e922032952cb154bb1b776d164cce69e 1606 418844f2f4b20850c0a23d30059362edadfe00fbfa04b6 1607 833fc4606deda441eb345c49b52d91063da7c55ecea7b3 1608 2e99a49a823264955803ce3ee220a2cc64cd4321e18ae2 1609 8bb1071c7746e8a3d69adef5113e21a01cab6809668793 1610 c2a94f 1611 denom₃.value = KUDOS:0.08 1612 denom₃.fee_withdraw = KUDOS:0.01 1613 denom₃.fee_deposit = KUDOS:0.01 1614 denom₃.fee_refresh = KUDOS:0.01 1615 denom₃.fee_refund = KUDOS:0.01 1616 merchant.priv = 7607240acc4563ebe2e38e76eaf61d74160d71c9a6670a 1617 e2e5147ce848767037 1618 merchant.pub = f54d646619723f7fa2ce79267953fdd8654cfcd0f2cfc0 1619 c5e880e3e0d0ab19f0 1620 merchant.url = https://merchant.taler.example.org/ 1621 merchant.payto = payto://x-taler-bank/bank.taler.example.org/merchant 1622 ]]></sourcecode> 1623 <section anchor="tc1-withdraw"> 1624 <name>Withdrawal</name> 1625 <sourcecode type="pseudocode"><![CDATA[ 1626 (W1) reserve key generation (wallet) 1627 1628 reserve.priv = d9641dab5c7f2474573871c25cae2f6c8924ace4157a56 1629 d128b1432e55a6c6ba 1630 reserve.pub = ec8ad5e4c6abcf4d0d597f0066a0e3ea0370d221973e06 1631 e73f4287148cb93c38 1632 ]]></sourcecode> 1633 <sourcecode type="pseudocode"><![CDATA[ 1634 (W2) coin generation and blinding (wallet) 1635 1636 batch_seed = 466431296486ed9cd71fc207254820a2c4a85aeb0b2041 1637 494f8bf1f8cd30f113 1638 coin_seed₀ = 88899daa409b8c4c4a91c8e39030d247d00b292eff952e 1639 36067fbe33f2d7ce48 1640 coin_seed₁ = f5be0b8790719072c7043c257f2c114cd8cb45ea5d98c4 1641 aa25d9025f45f1caeb 1642 blind_secret₀ = a3cbe2b0babf5bdfb98f45804acf63225c16e09be1677f 1643 705393df3f5de98ebf 1644 blind_secret₁ = 8ea6335ed3ff8a41f9fae95e9fd87382be402d6c26ef97 1645 2381dee6b3c1e9d775 1646 coin₀.priv = a5a38bb23a9f36564f9d4e566cdd7e3521b04f8ea4175d 1647 a726ac4e3ac540b485 1648 coin₁.priv = ae98c5207fe31e20a7b7a8677b780c6735ce69df32d308 1649 5d504010f23c59064a 1650 coin₀.pub = afbdf99f1a794add25bad59c9a3f442714e166adc99c57 1651 db991947669a36b185 1652 coin₁.pub = aa7118596b1adf89543e9afcf2925e516a782eed9d75c8 1653 abc4a470e7efdd7fe4 1654 h_denom₀ = 8653090e3f3f5efac9770a5dd0c97813940c191c9fa171 1655 3367f8bb1279b1e3d27f32d16ea7699501e5fc4d176725 1656 d76ab0307f9bdf9d0d263c2256a7f1c63143 1657 h_denom₁ = 1de6052bce12feaa2d26e3bba1789b0c2295028279f3ea 1658 ff8e1345448ba05390cff49656ed72a1f7ef6ee2c4a80f 1659 80eefa0d0f906e74305b0215c4194ab1c7b8 1660 planchet₀ = 64ede0cf40a952b95af4b09b22c6fd27a1ff6d0ae3920e 1661 a03fe14a8b547f1e14a2eea98443e7aa092075f6585103 1662 fb06c1d68fb4616bf33ae30a207e51840f1ae655a73418 1663 4a73d804df42650ce296954c9b61e249486468f7fda8a7 1664 4f85ec6ccdb34a66819fbeaf846b10087ffaf8e734428a 1665 907b96c6a112f8f943b3a8d55455c01b0daf55456acf07 1666 15874ff90fba45b265e2021a70997100fb18bfbef822c8 1667 475820b4855f141730751bcfad2e7eb46dd6c6a400a8a6 1668 a98486c4a2bce4d3407a0d0ba612faebb49428ba3a1986 1669 eddadb04b6790fbb7bd27cc0bd98341c60ec5b98027520 1670 2aedd4b0cf3b7ee1732c67c84db4b30b60b551cbf84922 1671 2c60e1 1672 planchet₁ = 41f8a6622c99b6a9c30d52d19fc2c20a39a481219de4b0 1673 f3e7f604efed5d962554ea13255785d10a037e14abd75d 1674 80a0aa9861df9d80a051c418ff197e68bd0eee61e6fd5d 1675 3214633734659e8bbd7dd2fe566bd41c537a5759bad9bb 1676 ca6b2eb7e3217e7d3cbefff192d83bd0527dbe0eff56df 1677 0b2e2062670d2873ca7766a7c1255e6fcf2c37e95de19f 1678 cad244f3986bab45c0a3aca726fc682455ea1166a23891 1679 52d7a67d181f035de6bdb97633888f0594c2f63dd39651 1680 34372507faf84f753759abd662d4c7e8df7e01149ff44d 1681 a3499ed49406d9398e86c4abf12a1f57f38002115ef728 1682 3e4d5422b41c752a0cce8c2c1a9b84e109b4554fc1150e 1683 f578b9 1684 h_planchet₀ = 888da42dbf4897a5d6d9420b827e340c74c0b0e973e140 1685 ad1c7b9abfc400a9ec5a86b3185e4c656dbe8e01125604 1686 616de83fa28910fae513d016f56c3ca94eb4 1687 h_planchet₁ = f20015bbe0147313e59f9e64ee9e836c192b5d504dbd33 1688 28fcfce41fbe9310d6aa96d91fdd77599c122cc5390ad7 1689 cb86d2c6d4261bd5950e7ec0f86959613841 1690 sig = 2ae0027dd4a196c4741d60e3e7ff933d7374fa5534d15f 1691 1cc2e96e9ab3392894c65ab6a0af31ccdb395db5c52677 1692 0077642502e27d4619d385a91dd13854e706 1693 ]]></sourcecode> 1694 <sourcecode type="pseudocode"><![CDATA[ 1695 (E1) coin issuance and signing (exchange) 1696 1697 total = KUDOS:7.7 1698 blind_sig₀ = 139af4e7e7f6e9e0391e22f78cb0b2c334e6d6667633a1 1699 92f56fde38ac9feec7841be59b2aa993084c50f70dfd96 1700 73dc723eec9d84c28ebd5f8104d1b0b29cf118cd64cbe3 1701 3925524a3363a1a6f24f59d47a404cf74680eee97cdeb8 1702 cc44a0b84f3db4496d9bed1224c0fbda64d40f84ef5447 1703 d764fb714ca8e72a23a882e749e47a519310f6d87b3e8d 1704 dc3e4ac4e541cdbfe7550c92f41c511b544d9fbdc2a729 1705 6b958e9df0b1394210aef4f1a780a129883d4bcb45425e 1706 ef96204a7eaa9daa7d21827ecbf4571cefe6dbe65314e6 1707 1c688175c1e81e01d4f0377c9c2312b6cc3487f2dd2cf8 1708 d85efde346f4d1a12de70bec4038b0bea0c505087c0e67 1709 ce4694 1710 blind_sig₁ = 89649cf83e2ba2cd75c7a1d01809c33d5d02fec8164925 1711 6215f13a8965ad37d8d47c264668ec187e46d75210ce60 1712 1362fbb15f61a24ec1d337dd2589b5a4ee0e77a8d9734a 1713 ca6a149b9f9b3a78c158b1f8cb243b8cbe9c2212290e8b 1714 c731d02382463f3e1cf0fc86c5472b8c96c5eaeac9c906 1715 4fdf7411f97935f27fd0bf88200440c7cc3e6960c5c515 1716 6aedb5a820077be08f1ac4b00780258d7b843b21d7baf2 1717 d969d1b3c77a08b4fe14b216fe78c7e4c0ae964fc06bf3 1718 dfe7ff20ec85fa4d5e5aec24d89848645ffadb0de3da80 1719 c6e41b96571ef28e3d132b7c3fd16a289e32389cffb653 1720 b4744fabf882342f0db9aef110351d8ffd7a3b86701f0f 1721 5034c8 1722 ]]></sourcecode> 1723 <sourcecode type="pseudocode"><![CDATA[ 1724 (W3) coin unblinding (wallet) 1725 1726 coin₀.sig = 9303650b8896b6619ca061f4bf44c1b02fb60784a2659d 1727 e7512b599e7e6524ad5a283c81d289d3ec75fc81e7f336 1728 bd41dd67a41b72a98d9171f0461c188535b555019079a1 1729 8b4491903797f62a034e5f277ce8f7f3f56fbe47e44113 1730 561fd414c841c2da97da1ae92df0e2cfbe3c26ad37f8ba 1731 b9bd71365ac536204cda7c21dc39891b5cbb4e213f75d4 1732 e09c248a7a59f6322fd011619b29ec25ad621dfa2d6fae 1733 9f8b91935caf54d0d30f4a03bf6beed6637a4054efbad7 1734 a41f9da434f07cfd2f7619e8a3c82b30e079ff9fe13fc0 1735 23fba7d627f4fb21e14467ce1db27767831eb1c3ad5c39 1736 f61437a0a70c300fd84cd9280474bb507768a868ea92fa 1737 905428 1738 coin₁.sig = 355aa5b6bf10591375f22a014640cd242f470834759fab 1739 4421b4d237a149bc3e5fbc8f073e1348da770983cd36df 1740 9cf72a30bfe55776744b2d787acb06ba25ccdef36e5269 1741 771fe4a38a1109e8b96437a3cc625003f7fdf4d0cc8793 1742 35584c5b13f2b29be1ea4d8a2da7826d608179d98b5edb 1743 11261e2048fbbba217a52ae862d1e78e30c0787ee40908 1744 f1bca708c434d5412a262eca6bcd0ac5890bfbbe7df6d6 1745 9a5544d0054716dfda47791546c177223606c0645858a1 1746 5b36887619a9d70a515f42897758bbe181765d7184cc92 1747 b5e2d743df1db9b30394b697117ad24811812febe0a3c5 1748 7cbb5cf7f6857378f57cd1149f745ed95fd1d342e9860f 1749 516469 1750 ]]></sourcecode> 1751 </section> 1752 <section anchor="tc1-payment"> 1753 <name>Payment and Deposit</name> 1754 <sourcecode type="pseudocode"><![CDATA[ 1755 (M1) order generation (merchant) 1756 1757 wire_salt = 4c5249caea865380e0e519fc38177686 1758 order.id = ORDER-40 1759 order.price = KUDOS:7.42 1760 order.max_fees = KUDOS:0.01 1761 ]]></sourcecode> 1762 <sourcecode type="pseudocode"><![CDATA[ 1763 (W1) nonce generation (wallet) 1764 1765 nonce.pub = 6729d69abd7d8218e02c953317b46bba2522efc2c19a7d 1766 a63194e9ef40fcbd0d 1767 ]]></sourcecode> 1768 <sourcecode type="pseudocode"><![CDATA[ 1769 (M2) contract generation (merchant) 1770 1771 h_wire = ec4e7258747a4de49628a27907b74f0aad097cfafaa595 1772 320f81786375430b67ae1ada754299bbc0472f5a1e8bae 1773 6fe8e5dc52683dd09490ff06fb2fa4f20ec2 1774 timestamp = Sat Feb 14 13:37:42 2026 1775 pay_deadline = Sat Feb 14 14:07:42 2026 1776 refund_deadline = Sun Feb 15 13:37:42 2026 1777 wire_deadline = Mon Feb 16 13:37:42 2026 1778 contract = { 1779 "version": 0, 1780 "summary": "Free Software Support", 1781 "order_id": "ORDER-40", 1782 "products": [], 1783 "timestamp": { 1784 "t_s": 1771076262 1785 }, 1786 "refund_deadline": { 1787 "t_s": 1771162662 1788 }, 1789 "pay_deadline": { 1790 "t_s": 1771078062 1791 }, 1792 "wire_transfer_deadline": { 1793 "t_s": 1771249062 1794 }, 1795 "merchant_pub": "YN6P8SGSE8ZQZ8PEF4K7JMZXV1JMSZ6GYB7W1HF8G3HY1M5B37R0", 1796 "merchant_base_url": "https://merchant.taler.example.org/", 1797 "merchant": { 1798 "name": "Taler Merchant" 1799 }, 1800 "h_wire": "XH774P3MF96Y95H8M9WGFDTF1APGJZ7TZAJSACGFG5W66XA31DKTW6PTEN19KEY08WQNM7MBNSQYHSEWA9M3VM4MJ3ZGDYSFMKS0XGG", 1801 "wire_method": "XXXX", 1802 "exchanges": [ 1803 { 1804 "url": "https://exchange.taler.example.org/", 1805 "priority": 1024, 1806 "master_pub": "7JTYK0HXPASKBZDKYA2AX5GEATZ8P20WD0CVHC11FWWB15DM64XG" 1807 } 1808 ], 1809 "nonce": "CWMXD6NXFP11HR1CJMSHFD3BQ8JJ5VY2R6D7V9HHJKMYYG7WQM6G", 1810 "amount": "KUDOS:7.42", 1811 "max_fee": "KUDOS:0.01" 1812 } 1813 h_contract = cc934a29efa612754edba0453d1b0ba175d6830d3ec2b2 1814 839a9a539d845a5da4622498e3819cb49206810688a93d 1815 e1989c6542d2cf1d71f64dc998193e76d535 1816 sig = c249ee766b4dd256560d48b367d05a41cf7169306247ec 1817 56c51c39412b34c11015e365c2b2836761ba020b7175e6 1818 0870572a6c7f780eeabb6f0777783064d602 1819 ]]></sourcecode> 1820 <sourcecode type="pseudocode"><![CDATA[ 1821 (W2) payment preparation (wallet) 1822 1823 contribution_net₀ = KUDOS:5.11 1824 contribution_net₁ = KUDOS:2.3 1825 sig₀ = 8876dce4ca504df355f17c783e8327ea29b2cbcd7dde60 1826 8b473644af3580621d3eb429022f6d1c4937328db478c6 1827 ed9784f6788e2e18dc16927efd4bc9c10908 1828 sig₁ = ee97e05b9bcd4b49b4518b8d6fdd90b5003178ec6bb4ac 1829 b5e9b14f189050c2320489042299b563e8ce0ba889d88c 1830 30d4b438b6d9a1609be3326ea9e12ee46a0b 1831 ]]></sourcecode> 1832 <sourcecode type="pseudocode"><![CDATA[ 1833 (M3) deposit preparation (merchant) 1834 1835 ]]></sourcecode> 1836 <sourcecode type="pseudocode"><![CDATA[ 1837 (E1) deposit check (exchange) 1838 1839 time_deposit = Sat Feb 14 13:37:44 2026 1840 sig = dffeeb7b3ee0094a2356a3bfed370ae0f082af00ab09a8 1841 35de67db0a8720488419c4da975e9b548e7e554767f1d1 1842 b380afc2ea72a93f83885ca3fbc138e4f80d 1843 ]]></sourcecode> 1844 <sourcecode type="pseudocode"><![CDATA[ 1845 (M2) deposit verification (merchant) 1846 1847 sig = e66d503c843d72da4b6eb95f872396449de25cbf80b9c2 1848 43d8c9ed2bde533d2460542c685bfdbf2eabc755510a60 1849 b97ed289711fd3f353cd80aa791e2e2f1e0d 1850 ]]></sourcecode> 1851 </section> 1852 <section anchor="tc1-refund"> 1853 <name>Refund</name> 1854 <sourcecode type="pseudocode"><![CDATA[ 1855 (W1) refund request (wallet) 1856 1857 ]]></sourcecode> 1858 <sourcecode type="pseudocode"><![CDATA[ 1859 (M1) refund processing (merchant) 1860 1861 id = 14365434601518496594 1862 value₀ = KUDOS:2.1 1863 sig₀ = a626cc04101e3abe295c217de5636be135be8935dfaf0b 1864 3589a8c7de22c3e6c7a581a031c0691476e82ee0e9798c 1865 3c8c8be6bc1066bd955acf4d1ce59eb7e10d 1866 ]]></sourcecode> 1867 <sourcecode type="pseudocode"><![CDATA[ 1868 (E1) refund check and confirmation (exchange) 1869 1870 sig₀ = be9dd11dec0e2fb2a2dfbc778b2d9bb21c665ecfa4d1b6 1871 c9d42747902f071631f84a946881bc787f8627a6871226 1872 4b06410b445f37e569edb7dbf77193b5990b 1873 ]]></sourcecode> 1874 <sourcecode type="pseudocode"><![CDATA[ 1875 (M2) refund confirmation (merchant) 1876 1877 value = KUDOS:2.1 1878 ]]></sourcecode> 1879 </section> 1880 <section anchor="tc1-refresh"> 1881 <name>Refresh</name> 1882 <sourcecode type="pseudocode"><![CDATA[ 1883 (W1) coin melting (wallet) 1884 1885 refresh_seed = 466431296486ed9cd71fc207254820a2c4a85aeb0b2041 1886 494f8bf1f8cd30f11394223cf8a82995804957876e9fa7 1887 1163506b4e5b8c8fa4db1b95d3e8c5c5fb5a 1888 for k = 0: 1889 batch_seedₖ = 415e62ec89f6397c834087efe396b127c6d5bdfe360145 1890 a6abbfc7a88c6504eee6e3f59db026cc5742c4065fd917 1891 bbf2b7f52e82e88409263130300279e52617 1892 transferₖ₀.priv = 5a08ea181dddd480b2e1e2294e1d886efe45070858adb3 1893 26e2d562dc330c8ca4 1894 transferₖ₁.priv = dccf4e1880b343687c7f39df603386a27510bd356ae1bc 1895 86f45ef9b7a8927613 1896 transferₖ₀.pub = ab4a35f7fc78a3d07e5828f0fae0295ebbe93e9ecc63c1 1897 09703f15816af8d000 1898 transferₖ₁.pub = 09893d5ef58fe696207e93cbd0cceb311265aa89745705 1899 9c40f366d59b028a29 1900 sharedₖ₀ = a7a9524dfc565b8006470ab90cba091a809f1de14eeda0 1901 dc98408f880d5cf587c2aa338ea1e3153ed8c624044f15 1902 19f3d8e8d6c731d7af6d0383b136a48a8e7f 1903 sharedₖ₁ = dd7051d4c4b03d78f0c5365ea0a2947f48604beee2e792 1904 0349d7a4371dbff00d9986202459277250461ab936d5f7 1905 45bb6c6c28e8badd7936002f25d9b97a65b2 1906 coinₖ₀.priv = c4fe7e3e64453e477e736ebabe2e5a7c4919eb2fa4bf02 1907 9e536d56a7eec59c9a 1908 coinₖ₁.priv = 409db2ea007fff35506607da6c67e52204097be8a114b7 1909 a654f53da392886e48 1910 coinₖ₀.pub = 65a93d56a84e8110fc2ae9c6ace89ddd9c625bd632501b 1911 663fefd047ee31feed 1912 coinₖ₁.pub = 7c61cf322d34ead1de43869690c70e22d9bae8f2354e0d 1913 d07e71c5736b506f41 1914 blind_secretₖ₀ = 0f53bafa492d5d90dd3ad13ba7b37b3c4a8b167dffc63f 1915 7940dcb340275be90b 1916 blind_secretₖ₁ = 799169aeddfec48aaab23a88df8d74318870c7b6cb3922 1917 5a3c43d4576db61f88 1918 planchetₖ₀ = 90997841cb9d3b4bef237213b1ee1da9286e775c1cc10d 1919 c78e32f836d7897500a587babeefed3f310a5b509c29d1 1920 91804b89d2aee75073f4d49d7ff5f60be991e0ae1a148e 1921 134b92c5c9537a59bc30516e0244e714ec2b6067337ffd 1922 970fd3987799d2ac7b3e3430068c923974751864ed8f4d 1923 087b0cd62e0edb807d9ac4bf70e68c9d774a0f26947413 1924 0f4fa5a8f4e0a5ac67ef6c73a1cb486792605f447384ea 1925 9deb040f851953db240a5f23401e0d75f93f810132ed9e 1926 782ba05b4f78ce7cafc501925ce0bde12e58ef48861969 1927 038a95802a1d943b2ce31a3278a1cb4f14cc12ff2ffee1 1928 3aba0ee151145a3b7abdd1a00e0684a57a1b2a0fd97348 1929 81243b 1930 planchetₖ₁ = 0562f874175e223f087e7950f2082e869bca1ded7087be 1931 27a98f1f9be30a38f33e9a98ca5efb6f15536df774ce32 1932 1efd36909d67869e704db3ff352c76298c0d33014a32ff 1933 636c22866b5e5d6dbc5e6c50f630d95112e8916fd23ec4 1934 88eb457f55ad3a29d50c3c7387b4ee1045cbe4d37241e9 1935 b958d1642b34f4a15a259b344163dbf73bc55e5b99e0d4 1936 6ba59b7dca0a1fbe859f6f7d5756d6afff58571fdac617 1937 48a81e5e94e784c2d5de60a192d86c0529e35f2efa29d4 1938 2e0ce8526db5fd3258a470a43d55c184287fe0c639ff8a 1939 eea1ee64a61d6466d15e20c8203a73ce1b2fc7b2949947 1940 f9804b0710e41351af67cc30b86108dca7ea0208062ae6 1941 0be2e5 1942 h_planchetₖ₀ = ba016fdedb6c5033f1f870edd9ab10d0dd116c0e3a8483 1943 0ddd44c9aed5a2844aea96146cf7c72153a910ca3d3de1 1944 faab7fca5e1c4079e2e0c680410cf68ee27b 1945 h_planchetₖ₁ = c4f4451f85f02c950fba164ccc52fd2123576ddad6ab87 1946 c25b175a33aed8afff5c5866b2fbcec6ef67a1367f91e5 1947 da56041371bc9e8cefd2a93ad386504568a3 1948 h_planchetsₖ = 7e420d01a6413fb6cc300257031f37ab2d456583d3189c 1949 3e5f7049c1c61f49c7918289b7cd169cebd0bb81ca0a83 1950 2f2c4c6c7529e861a88d65c6d3ef5fd540ff 1951 for k = 1: 1952 batch_seedₖ = 0311a9766673b9df343498afcd6f6926b9bd6352201351 1953 5c072a0b5a3af98aeb8158869f3ece08532473980a652d 1954 d6479f296a28504b850791f9775e3b0f8436 1955 transferₖ₀.priv = 4a3d33228a7c1d6330fb2ec827256aad75f7ea56712072 1956 f8ff69238b47e98895 1957 transferₖ₁.priv = ad0b2c176a9564ea7aee7c55ddd92af22d777ea4a8605b 1958 d486d8ccc31bb1402f 1959 transferₖ₀.pub = 1839010739d0450e9a0702167d5106dbcb0a81641e0080 1960 716785850e60bc541d 1961 transferₖ₁.pub = 16a20ed27a63c204d94ef3d0c2b554343567d319afc70d 1962 856cc6a61c3bdaa142 1963 sharedₖ₀ = 32751bb2cf2a3106593aac0fb38172943c54a96992b22a 1964 7927ce37fcf0b9b4aa4671033c93ece3c70f2033e4c52a 1965 953bf46254db7f6d7feb926d78b28bb60901 1966 sharedₖ₁ = 2c4118e0d52fe1851410fb70b60cc5b3fa6bbb53df8acc 1967 5a379c65d9f89c2ba37ea732e76d081e03d845dd2f3ef8 1968 a53b682941d4e598a17823ea06cd28058e8d 1969 coinₖ₀.priv = 16977a220b0bfcb2a0ef82faa3afea901d0cf3e6829905 1970 85b63d9c855be5d5aa 1971 coinₖ₁.priv = 1b5bab529c09f313f2a18e3d2712c1a7e0548f15651b40 1972 af12b22c17ca861273 1973 coinₖ₀.pub = 4b53ebc94ca1a96ca4795a0ce1254f70ba2fdd72528d57 1974 4f4bb47d26fe845239 1975 coinₖ₁.pub = 6de1ac4370a5336349ed50cfd4d6298b193504c1325614 1976 9cb0fa85c1f9a178c7 1977 blind_secretₖ₀ = 30e3a32819cdc5a2e9b28d7953bba0038eaf701ceaf691 1978 a6bf44833ae6f305a9 1979 blind_secretₖ₁ = 62ac62d9df0b5f71f0b43329baa15c5e79f46b09fe432f 1980 cdeb3a9100b31a0fa2 1981 planchetₖ₀ = 73cbbfab1a58b12c55b4eecf705c9db8fb953f52bfb4fa 1982 9922f39641efb85802659d266f979c819294af91cb395c 1983 f93f67a0a6b561e445b0a138f04e6428222ccb5ef92a21 1984 1da2218953e8aa108f339bbce666a71640f555570d6fec 1985 a446b67be82edfa3f90697d5558d7b7707bb87bf790d35 1986 35e429d705367f0ceb3fea30f7666ed428679bed440540 1987 3f2a9cf5cf75a43f16fc5b63276e9a18bea0c0864587c0 1988 a884d1a474f3a248e36183a067e59496d8968427c55e63 1989 ac3f0052fc20fea5b9f01b19ee776e7c1bdfa576be42d2 1990 1e7214606bea3277878cb7beb7015a242bd9bfaee620dc 1991 ccdfda8f34b7174ed28766000d22dd552cd487fdaf9cd0 1992 cc1f5f 1993 planchetₖ₁ = 922bf6290e8f5e8746f68cda30cee9d368f3988b93d26d 1994 c753e082fe56db8191430ce8ef78f1175d651b491e6cc6 1995 7e0cf34253abcf3c3bbae44b4620ca0879171710caac83 1996 89704d99d5d49da5de04b44f03d03b30df9d872611d779 1997 6c6903fdee77a68a29aabac5c332588aaecf2a5e8cbfe4 1998 446d33f423040e7eda99268f2ca558615b541cd912ef30 1999 2a9f079705b9d1785839a593d07d8b79756f0077cb5169 2000 a3a88f08ee7371419c940f35250d2aa52bcfc6beab73b9 2001 72f31d3b5de16e55c590788cb4443dc0de7d2cb6993555 2002 0b04b8bcc2c33669f97ed1d36f29c594c6f0f84a72bd73 2003 f76c7617e748356f7989a98deca97f360fcf2d087f9bcc 2004 d61732 2005 h_planchetₖ₀ = 6523f04c8eacea9af24c08905eb009c8e15a6c62adfae2 2006 fcee6813bba22ba014c3c831cae6fb63a2a889af0e99ea 2007 d40a39b57d42043dd67fe4e446c7691558c3 2008 h_planchetₖ₁ = f86bf5d2bf56d182ff70b0ecf635401bce1dab4bd52f40 2009 023adef27ca2a4165d19b0de911a6a6e41e5811ea1d9cd 2010 9bb17dbf9ee518b1f3bfec644e8a36f7fb2e 2011 h_planchetsₖ = f63471c1555835b7032ffa41db189f013d1f26dd5bf1fd 2012 c79bf18ea8c3f24ec7f31f0b4c1688d7a6a729c7b2c2ee 2013 f42a5ce3524ca23a566d74e708eac487b1dc 2014 for k = 2: 2015 batch_seedₖ = 35e8f7b41e25d3ca2c8e70d02be85843b53703f199809f 2016 98527e316bda6a457a2fab9d327f96242c4e0afbd6214f 2017 aee6a5172aca2b49ad37a12590dc3bbc3f58 2018 transferₖ₀.priv = 1ca613b8fbe4a341b2fc617687553e778de9b8d40c462a 2019 88bc1ac169d2984da7 2020 transferₖ₁.priv = bb8196a4a5b9a646c5424664b8505eb8781ded006c74e7 2021 cc719e7a2cc730ae88 2022 transferₖ₀.pub = e21056df9fdf4cd94a4175f94a48fce623db6f2bc4097d 2023 818f839ec421fe974f 2024 transferₖ₁.pub = 0409b44ddfed03111d7dab5af1b71d8b2597ee50772a9f 2025 272e799133718fd571 2026 sharedₖ₀ = 01a355feafd4daafcd6341597b73eee6ca7ad5dfb78758 2027 88a373434043d17087ab882cca24e580985068eb1b39b8 2028 c0e7f81f03ccca337961cd1d6a528abd3cd1 2029 sharedₖ₁ = 39cdc5377c7295d1e997a43fdc2aac0f5005e64211f7f0 2030 9da36db035ddad5bc32c2dcc4bd5fe1e0d3e471ae8fcfa 2031 9cac0fefa8078570b894164194829e54dabf 2032 coinₖ₀.priv = 343d0b591fc0c495d2e7cb68f2cb0c24d9b274e3ae8504 2033 1dd94454d2856059f6 2034 coinₖ₁.priv = 57c9447a9a34e4b7ed5f4bc71122d76dee9583cb578eb8 2035 eff2e837bc9a0591e6 2036 coinₖ₀.pub = 3b9fb220f7679b3488f8e2710f41d5e6cfee1b6c23bef3 2037 04d9dbfc404341fccd 2038 coinₖ₁.pub = 6ee277e7bcd2584c5ee8f46cc24b531515a33388e6035d 2039 00b33df8ce6a7edaee 2040 blind_secretₖ₀ = f5d25d0124dce3b3529325b6512fd34293448b710217fa 2041 885ba5d80705d16a64 2042 blind_secretₖ₁ = 974dc1b68e4a7613346375372ead838842bab6335d1696 2043 af3b6a2ad249fee4ee 2044 planchetₖ₀ = 55e3f72dfd4c53ba21f6f9e108c34f8f6bf0b69dd8daab 2045 bf4386a7e3a31c7e33ecda1dc54a31a1d5f97b810806f9 2046 d845af20716f4aad733026ff0f6ad0219a1f92d937ade7 2047 6b268f8d436fdf6ca63d9051008efa3af022c9846fdecc 2048 79ce27c8e59042795f2f8a4bc0a792b44bc64c8e6e7c27 2049 3a107d96081142b1d06718e28b32bc733ff36e7b95538f 2050 b2ec30d1242965f9ab40debe4ed845227b7a4a4d795286 2051 6b798253cf1eb664a1d832c2397d044122d24982fb88bd 2052 68f81efa45f80bdbe918680004bdea5dc2e4e76dfed297 2053 af200350793f820aa094e1b26c79e2c2faff866410e741 2054 1bb662c94be10a841ec9db1432d198a4a01c2911326cec 2055 da502a 2056 planchetₖ₁ = 978fca7d513afac1d6ec6561fd967218bf0d84e388a23f 2057 b085f1c37493d765090b90c0c23ba20647114c0f34d8db 2058 1041809a66dfeab96c36477be8342ff4f2660cfd8f0011 2059 14f2aab3d12d983d82b92fcfb38e97fa83142980a9f919 2060 7e794859f439b18491600ea92bcdc1af7ebe4784eb0229 2061 bd287b9c71cdde177d4576d7907f9d643a363e09685293 2062 b7474c990d5d8cdc119d7448d768412e40e8461ea88109 2063 461e37f3a76178df074c942e99062ce717eba48903c7a0 2064 cd27889429ac5a657ca50efd441363c18f9968b33962e4 2065 960bf2005fc0fb2b8050024bf34e8f608f4dade5554aab 2066 1d28478f5bc1c5939c939ff5b9b11f225e7eb275887d3a 2067 475a34 2068 h_planchetₖ₀ = 5c9603dc7240248f0a93107bce217562d60943c9976770 2069 d11c1fd4c9f73fe7f2f3696696b37fb0fa73331c301e8d 2070 d7adceafb23456bfcb6d44063d61f5db239e 2071 h_planchetₖ₁ = d905de829b86b21eb19c036320d3e11571e6ca8390e81f 2072 86e4569e3cc12189ea10cd752c738972a809fa292818a1 2073 f13367c389a3f505f084c5001615de3b647e 2074 h_planchetsₖ = 802838537720786bbe61a0752397056c3a7f7bc332a54d 2075 c5a649452a9a74fef79c2c59deaf1e03cf73f85f241f28 2076 61a50f2f859d95c3c660ab5e57b448526036 2077 value = KUDOS:0.25 2078 commitment = ba2a18eb9cc878b20dde4679910aede08b37b58e47df25 2079 2a245598e0671ed6fc012c9cc245d13f9759d777d80d51 2080 d4a29bcdba486109d83075b8bf47fc518928 2081 sig = 62ce04a6a6dd6b3f50792e34b51ccc10d2552425800566 2082 90248790f6280db11f6f29753f601f19e8504ea378574a 2083 dec5b1fc6f5509f3ec79af3110bb4cd4670a 2084 ]]></sourcecode> 2085 <sourcecode type="pseudocode"><![CDATA[ 2086 (E1) gamma selection and coin signing (exchange) 2087 2088 ɣ = 1 2089 blind_sig₀ = 1885a01f26936f28dfd201a7dd615dacd68a287e17aa8d 2090 d1e4f3a1925047049a491c1b76ca687431faf6fd290deb 2091 4dc80601ba79d7754c84a8d8550a0b166104b6ec7e611f 2092 bc577aff339033d421035578029068a84bd4fe5e212670 2093 fd2ce7091ef9950ee48778aae2855a99555308ae90b72a 2094 b1fb53fea714841c94e256705aae8efeebc877efd376a8 2095 78c6e2cb4e811a267484e4da8e13206c1dde7ef3646528 2096 c1d8bf48096eabcc454ed5ee180e3fe7229785a51a3b8b 2097 d3fba176c05baf0eb82e99d225cfa5f9359d07d2510013 2098 301a7bdf815a7db36d400bc00ca861dbe1402ec6dacbba 2099 901e8c8e4e8f1912e63e2a440e667cea243d46e08026d3 2100 738fab 2101 blind_sig₁ = 9c10e5b88fe3563bdaba5934447baad4d05e66a9075102 2102 7a5cbdd2cf0cd9bcaaec68935d3c85509894247ab569d9 2103 7fd4825a7972d48dbab1c9cbf791776c96a8dcf48caf2e 2104 542f5e50f86d794066b7bc82e975c55995b40cf10d00e6 2105 4904530dad5c396543fadf88b79f81b00c8ebbaf2f6731 2106 f434c5c3d72b451586d0412b0272a6c6ac5ba5ef59af57 2107 969d4f985ea513187c8020a318d4a9c9711ccfdb5aa8b9 2108 ebd93b20e129c3447771a1dfb1b1bbdccaef56323005c5 2109 6116b1df97ace4ae6f6865e5467a96d2fad9cb4c9cf0c0 2110 3cf774ad1dd8f5b0a0fe218ac78b37c4435e4f5616c2fd 2111 96dba36f3c7c1973835fe53c95839ed11c792ad011c9fb 2112 1ce55c 2113 sig = 6eb68d755e7e554ade9f9f21e3a04b83a74753ec136f98 2114 981ec2369d0fd56f88c274fe44482f425f1142a447627b 2115 71e2117d9991d89dfbf97441b881963a360a 2116 ]]></sourcecode> 2117 <sourcecode type="pseudocode"><![CDATA[ 2118 (W2) secret revelation (wallet) 2119 2120 revealed_seed₀ = 415e62ec89f6397c834087efe396b127c6d5bdfe360145 2121 a6abbfc7a88c6504eee6e3f59db026cc5742c4065fd917 2122 bbf2b7f52e82e88409263130300279e52617 2123 revealed_seed₂ = 35e8f7b41e25d3ca2c8e70d02be85843b53703f199809f 2124 98527e316bda6a457a2fab9d327f96242c4e0afbd6214f 2125 aee6a5172aca2b49ad37a12590dc3bbc3f58 2126 ]]></sourcecode> 2127 <sourcecode type="pseudocode"><![CDATA[ 2128 (E2) commitment validation (exchange) 2129 2130 ]]></sourcecode> 2131 <sourcecode type="pseudocode"><![CDATA[ 2132 (W3) coin unblinding (wallet) 2133 2134 coinᵧ₀.sig = 68773443fe6cf88ddea6f6614213f12ec7ded4fbb39fa0 2135 a4ffc1a68bbfc363be0b33bd03a41d31c8ffe331614ee4 2136 b986679ac8e51aaa0903eee492d0ff81327589c842ac80 2137 a6b47e0833840935e9cd543fbbb91c5b80a591e01eb34d 2138 7bb5aa3fe837b22f8dcfcaf0ee9d71d93c866f00a8f787 2139 def0b79eaa4e6e96c420990b05c2b82c378757ce220e96 2140 734e547a6962148848d2ebb66e9c67a40115a958d21c05 2141 c7e0a0db72e505076e35ddca7b09b603b55dad394c1d12 2142 ff4b6b219feafc3ca24c43c36ad2da9fa632ec1bcfc057 2143 2db80d0afcc9875182def7983385f872005033d7ea7080 2144 bce0df982a134f5ae2dccb2cdc304278c809979252ac28 2145 2a76e1 2146 coinᵧ₁.sig = 1551b2dcf6daa264d4c96452f46c88e7b4ca3955642da4 2147 5e375cb319602897ceb75eda64060afd17002b63fdd39c 2148 c0f86c473a530813c23958573431e2fcd2277cc853f5ab 2149 6a20a9e7499154420f0cd8d13990d45423e61a6651a614 2150 7e8a146a10fd5d63e085c2c4c133d4db0827df1d4fed10 2151 d1e6eadc566e167a17fd36ee884900db9a8cc4b82a02b7 2152 ca0cfacb7d391f535da3011ca469146f239d621fcdfc10 2153 563bfe6ac4c962109e2fc39aa236151f15a9c85b8e0e4e 2154 2ee4f6b6b5f54337c184936e2fe4029e2d39ffe6953f7d 2155 cf208ba062334e8595dbb9784857df770377a59dee2a8b 2156 ee4e9c10e662f15dedd0379849ebc4a7a02a31f1ebd8a8 2157 e55432 2158 coin₂ = coinᵧ₀ 2159 coin₃ = coinᵧ₁ 2160 ]]></sourcecode> 2161 </section> 2162 <section anchor="tc1-link"> 2163 <name>Link</name> 2164 <sourcecode type="pseudocode"><![CDATA[ 2165 (W1) history request (wallet) 2166 2167 sig = ceb8dc24e263252b479376b15ae141e4da28dd712c37c4 2168 81a163d549b44afdd018d04fe709462a56739b3cc0671c 2169 2cc0333b7e5da25210b8bda54d83d25f5407 2170 ]]></sourcecode> 2171 <sourcecode type="pseudocode"><![CDATA[ 2172 (E1) refresh secret lookup (exchange) 2173 2174 ]]></sourcecode> 2175 <sourcecode type="pseudocode"><![CDATA[ 2176 (W2) coin acquisition (wallet) 2177 2178 ]]></sourcecode> 2179 </section> 2180 <section anchor="tc1-w2w-account"> 2181 <name>Account Creation</name> 2182 </section> 2183 <section anchor="tc1-w2w-push"> 2184 <name>Push Payment</name> 2185 </section> 2186 <section anchor="tc1-w2w-pull"> 2187 <name>Pull Payment</name> 2188 </section> 2189 <section anchor="tc1-withdraw-recoup"> 2190 <name>Recoup Withdrawal</name> 2191 </section> 2192 <section anchor="tc1-refresh-recoup"> 2193 <name>Recoup Refresh</name> 2194 </section> 2195 </section> 2196 <section anchor="test-case-2"> 2197 <name>Test Case 2</name> 2198 </section> 2199 </section> 2200 <section anchor="change-log"> 2201 <name>Change log</name> 2202 </section> 2203 <section numbered="false" anchor="acknowledgments"> 2204 <name>Acknowledgments</name> 2205 <t>[ TBD ]</t> 2206 <t>This work was supported in part by the German Federal Ministry of 2207 Education and Research (BMBF) within the project Concrete Contracts.</t> 2208 </section> 2209 </back> 2210 <!-- ##markdown-source: 2211 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 2496 loPB86Y+YkEkdk2FXr6ma1isKluM4LOcn5v8YkzCpCqby1TgSGg9Hy5nQ/q3 2497 XWyBJg+ngclYPTDvK5q7Igz30nd/K6nJdTb59pKG8pcHU5fOceh2aihyS0pT 2498 gHd7rm20yKx0yO3Hb90rv1ZYh3/Vln3gYmUKNVpko8cmk43HJpPOY8EzLVfz 2499 8fIyuE3ppcpf4TIY/OHr4PnHd4I/fENPPbz1+NbGE49htjBtgmV03wo995zs 2500 /e80bYOpKRgvApO0rcZv7I24ijLLX89gcV0iKzV4ZRvYpFh8QI6azQh+4v3D 2501 7rtnFyZr/dIUfdTuIWn705l18uaz1elZ97qU1vU0/rLg2WQyM+URpkrJptK+ 2502 8O/Kplm64harzv/Rlj+4v75fzxw+cS8GPPG+rFeRJsk+GtFO1JUu/h1rTUoz 2503 7VVd5NAd0RaejPnmA9+fbFaajKjww5aQtFq6IhGqpKn7NsWG9l40S/qzZmLr 2504 1SSjQTKqS4NMBcjs9dAc+7XmQkUboFqrLMh+9acO5f58suntjwYpde/3srfh 2505 jpqHNjXq2oZsZCVJmxfbOSk6MauFONQGfFHvWUvWqH0+goC4LXCvI5u1+tm9 2506 fX86OXCRD+Ix9+F/P2mPZcSWBipo+f6Oqm1jHbhLl+hlenSB1O6h//u2of/3 2507 taGhCmjocuT1MHW33hMadaI37doe4v+GGGts73U5DcHCnWP8eW2MuvjIDLC+ 2508 uWu2gvpv7MBFdAHdYqNzhjLusijS769n85eL2t+xF3c2b56DRrLVSqD6H/V8 2509 9ptWr056XvvrPRcTenc1ujw35VRkA5zaMtsS1ddHtd9zSPdf2Y6oGqYZ2FV2 2510 YVgz4boeczwNAb7WBJg+ZhZgMkdHWxLWfifhR0GrjNYNBLpP3TsJjYmO/AXG 2511 8b4tm+poYqMhwWrwBlaGFc/Miy/Jbnb0Le3m/cdfOG1tDKimS57XXhX+ek53 2512 MFCZYnB7NLiFVYrxlMNSm4v0zfshjW0wEbgz/YbTjWT0ssDpzPYwGnwMLDRd 2513 nQvt7ASAjFH/c31BinfqwndifDqk7afg4eXSv4Fy73yGxZnECrqgbrq0X5q3 2514 pe6PLMig5d+me7vYhjNUn1Kd8wVofUy4FWAnliLVZRHFSkQijtNKibiKioTr 2515 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 2861 2V4BAA== 2862 2863 --> 2864 2865 </rfc>