lsd0009

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

commit 3109e3cc293c6a35a39bb409f217a49d1d039f57
parent 963d59e9ef80f2bdf2a7ff1c4d2057b81f92712b
Author: Mikolai Gütschow <mikolai.guetschow@tu-dresden.de>
Date:   Wed,  1 Apr 2026 17:45:07 +0200

Makefile: update to kdrfc -c, make sure to have xml2rfc version 3.32.0 installed

Diffstat:
MMakefile | 5++---
Mdraft-guetschow-taler-protocol.xml | 1046++++++++++++++++++++++++++++++++++++-------------------------------------------
2 files changed, 480 insertions(+), 571 deletions(-)

diff --git a/Makefile b/Makefile @@ -1,12 +1,11 @@ all: txt html draft-guetschow-taler-protocol.xml: draft-guetschow-taler-protocol.md - kramdown-rfc draft-guetschow-taler-protocol.md > draft-guetschow-taler-protocol.xml + kdrfc -c draft-guetschow-taler-protocol.md + mv draft-guetschow-taler-protocol.v2v3.xml draft-guetschow-taler-protocol.xml html: draft-guetschow-taler-protocol.xml xml2rfc --html draft-guetschow-taler-protocol.xml - # workaround for https://github.com/ietf-tools/xml2rfc/issues/628#issuecomment-4162012035 - sed -i 's/\&amp;#/\&#/g' draft-guetschow-taler-protocol.html txt: draft-guetschow-taler-protocol.xml xml2rfc draft-guetschow-taler-protocol.xml diff --git a/draft-guetschow-taler-protocol.xml b/draft-guetschow-taler-protocol.xml @@ -1,21 +1,17 @@ -<?xml version="1.0" encoding="UTF-8"?> - <?xml-stylesheet type="text/xsl" href="rfc2629.xslt" ?> - <!-- generated by https://github.com/cabo/kramdown-rfc version 1.7.35 (Ruby 3.1.2) --> - - -<!DOCTYPE rfc [ +<?xml version='1.0' encoding='utf-8'?> +<!DOCTYPE rfc [ <!ENTITY nbsp "&#160;"> <!ENTITY zwsp "&#8203;"> <!ENTITY nbhy "&#8209;"> <!ENTITY wj "&#8288;"> - ]> - - -<rfc ipr="trust200902" docName="draft-guetschow-taler-protocol" category="info" submissionType="independent" tocInclude="true" sortRefs="true" symRefs="true"> +<?xml-stylesheet type="text/xsl" href="rfc2629.xslt" ?> +<!-- generated by https://github.com/cabo/kramdown-rfc version 1.7.35 (Ruby 3.1.2) --> +<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"> + <!-- xml2rfc v2v3 conversion 3.32.0 --> <front> <title>The GNU Taler Protocol</title> - + <seriesInfo name="Internet-Draft" value="draft-guetschow-taler-protocol"/> <author initials="M." surname="Gütschow" fullname="Mikolai Gütschow"> <organization abbrev="TU Dresden">TUD Dresden University of Technology</organization> <address> @@ -28,63 +24,66 @@ <email>mikolai.guetschow@tu-dresden.de</email> </address> </author> - - <date year="2026" month="March" day="31"/> - - + <date year="2026" month="April" day="01"/> <workgroup>independent</workgroup> - <keyword>taler</keyword> <keyword>cryptography</keyword> <keyword>ecash</keyword> <keyword>payments</keyword> - + <keyword>taler</keyword> + <keyword>cryptography</keyword> + <keyword>ecash</keyword> + <keyword>payments</keyword> <abstract> - - -<?line 43?> + <?line 43?> <t>[ TBW ]</t> - - - </abstract> - - - </front> - <middle> + <?line 47?> - -<?line 47?> - -<section anchor="introduction"><name>Introduction</name> - -<t>[ TBW ]</t> - -<t>Beware that this document is still work-in-progress and may contain errors. +<section anchor="introduction"> + <name>Introduction</name> + <t>[ TBW ]</t> + <t>Beware that this document is still work-in-progress and may contain errors. Use at your own risk!</t> - -</section> -<section anchor="notation"><name>Notation</name> - -<t><list style="symbols"> - <t><spanx style="verb">"abc"</spanx> denotes the literal string <spanx style="verb">abc</spanx> encoded as ASCII <xref target="RFC20"></xref></t> - <t><spanx style="verb">a | b</spanx> denotes the concatenation of a with b</t> - <t><spanx style="verb">len(a)</spanx> denotes the length in bytes of the byte string a</t> - <t><spanx style="verb">padZero(y, a)</spanx> denotes the byte string a, zero-padded to the length of y bytes</t> - <t><spanx style="verb">bits(x)</spanx>/<spanx style="verb">bytes(x)</spanx> denotes the minimal number of bits/bytes necessary to represent the multiple precision integer x</t> - <t><spanx style="verb">uint(y, x)</spanx> denotes the <spanx style="verb">y</spanx> least significant bits of the integer <spanx style="verb">x</spanx> encoded in network byte order (big endian)</t> - <t><spanx style="verb">uint16(x)</spanx>/<spanx style="verb">uint32(x)</spanx>/<spanx style="verb">uint64(x)</spanx>/<spanx style="verb">uint256(x)</spanx>/<spanx style="verb">uint512(x)</spanx> is equivalent to <spanx style="verb">uint(16, x)</spanx>/<spanx style="verb">uint(32, x)</spanx>/<spanx style="verb">uint(64, x)</spanx>/<spanx style="verb">uint(256, x)</spanx>/<spanx style="verb">uint(512, x)</spanx>, respectively</t> - <t><spanx style="verb">random(y)</spanx> denotes a randomly generated sequence of y bits</t> - <t><spanx style="verb">a * b (mod N)</spanx> / <spanx style="verb">a ** b (mod N)</spanx> denotes the multiplication / exponentiation of multiple precision integers a and b, modulo N</t> -</list></t> - -</section> -<section anchor="cryptographic-primitives"><name>Cryptographic Primitives</name> - -<section anchor="cryptographic-hash-functions"><name>Cryptographic Hash Functions</name> - -<section anchor="sha256"><name>SHA-256</name> - -<figure><artwork><![CDATA[ + </section> + <section anchor="notation"> + <name>Notation</name> + <ul spacing="normal"> + <li> + <t><tt>"abc"</tt> denotes the literal string <tt>abc</tt> encoded as ASCII <xref target="RFC20"/></t> + </li> + <li> + <t><tt>a | b</tt> denotes the concatenation of a with b</t> + </li> + <li> + <t><tt>len(a)</tt> denotes the length in bytes of the byte string a</t> + </li> + <li> + <t><tt>padZero(y, a)</tt> denotes the byte string a, zero-padded to the length of y bytes</t> + </li> + <li> + <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> + </li> + <li> + <t><tt>uint(y, x)</tt> denotes the <tt>y</tt> least significant bits of the integer <tt>x</tt> encoded in network byte order (big endian)</t> + </li> + <li> + <t><tt>uint16(x)</tt>/<tt>uint32(x)</tt>/<tt>uint64(x)</tt>/<tt>uint256(x)</tt>/<tt>uint512(x)</tt> is equivalent to <tt>uint(16, x)</tt>/<tt>uint(32, x)</tt>/<tt>uint(64, x)</tt>/<tt>uint(256, x)</tt>/<tt>uint(512, x)</tt>, respectively</t> + </li> + <li> + <t><tt>random(y)</tt> denotes a randomly generated sequence of y bits</t> + </li> + <li> + <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> + </li> + </ul> + </section> + <section anchor="cryptographic-primitives"> + <name>Cryptographic Primitives</name> + <section anchor="cryptographic-hash-functions"> + <name>Cryptographic Hash Functions</name> + <section anchor="sha256"> + <name>SHA-256</name> + <artwork><![CDATA[ SHA-256(msg) -> hash Input: @@ -92,14 +91,12 @@ Input: Output: hash message digest of fixed length HashLen = 32 octets -]]></artwork></figure> - -<t><spanx style="verb">hash</spanx> is the output of SHA-256 as per Sections 4.1, 5.1, 6.1, and 6.2 of <xref target="RFC6234"></xref>.</t> - -</section> -<section anchor="sha512"><name>SHA-512</name> - -<figure><artwork><![CDATA[ +]]></artwork> + <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> + </section> + <section anchor="sha512"> + <name>SHA-512</name> + <artwork><![CDATA[ SHA-512(msg) -> hash Input: @@ -107,14 +104,12 @@ Input: Output: hash message digest of fixed length HashLen = 64 octets -]]></artwork></figure> - -<t><spanx style="verb">hash</spanx> is the output of SHA-512 as per Sections 4.2, 5.2, 6.3, and 6.4 of <xref target="RFC6234"></xref>.</t> - -</section> -<section anchor="sha512-trunc"><name>SHA-512-256 (truncated SHA-512)</name> - -<figure><artwork><![CDATA[ +]]></artwork> + <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> + </section> + <section anchor="sha512-trunc"> + <name>SHA-512-256 (truncated SHA-512)</name> + <artwork><![CDATA[ SHA-512-256(msg) -> hash Input: @@ -122,24 +117,20 @@ Input: Output: hash message digest of fixed length HashLen = 32 octets -]]></artwork></figure> - -<t>The output <spanx style="verb">hash</spanx> corresponds to the first 32 octets of the output of SHA-512 defined in <xref target="sha512"/>:</t> - -<figure><artwork><![CDATA[ +]]></artwork> + <t>The output <tt>hash</tt> corresponds to the first 32 octets of the output of SHA-512 defined in <xref target="sha512"/>:</t> + <artwork><![CDATA[ temp = SHA-512(msg) hash = temp[0:31] -]]></artwork></figure> - -<t>Note that this operation differs from SHA-512/256 as defined in <xref target="SHS"></xref> in the initial hash value.</t> - -</section> -</section> -<section anchor="message-authentication-codes"><name>Message Authentication Codes</name> - -<section anchor="hmac"><name>HMAC</name> - -<figure><artwork><![CDATA[ +]]></artwork> + <t>Note that this operation differs from SHA-512/256 as defined in <xref target="SHS"/> in the initial hash value.</t> + </section> + </section> + <section anchor="message-authentication-codes"> + <name>Message Authentication Codes</name> + <section anchor="hmac"> + <name>HMAC</name> + <artwork><![CDATA[ HMAC-Hash(key, text) -> out Option: @@ -151,21 +142,18 @@ Input: Output: out output of length HashLen -]]></artwork></figure> - -<t><spanx style="verb">out</spanx> is calculated as defined in <xref target="RFC2104"></xref>.</t> - -</section> -</section> -<section anchor="key-derivation-functions"><name>Key Derivation Functions</name> - -<section anchor="hkdf"><name>HKDF</name> - -<t>The Hashed Key Derivation Function (HKDF) used in Taler is an instantiation of <xref target="RFC5869"></xref> -with two different hash functions for the Extract and Expand step as suggested in <xref target="HKDF"></xref>: -<spanx style="verb">HKDF-Extract</spanx> uses <spanx style="verb">HMAC-SHA512</spanx>, while <spanx style="verb">HKDF-Expand</spanx> uses <spanx style="verb">HMAC-SHA256</spanx> (cf. <xref target="hmac"/>).</t> - -<figure><artwork><![CDATA[ +]]></artwork> + <t><tt>out</tt> is calculated as defined in <xref target="RFC2104"/>.</t> + </section> + </section> + <section anchor="key-derivation-functions"> + <name>Key Derivation Functions</name> + <section anchor="hkdf"> + <name>HKDF</name> + <t>The Hashed Key Derivation Function (HKDF) used in Taler is an instantiation of <xref target="RFC5869"/> +with two different hash functions for the Extract and Expand step as suggested in <xref target="HKDF"/>: +<tt>HKDF-Extract</tt> uses <tt>HMAC-SHA512</tt>, while <tt>HKDF-Expand</tt> uses <tt>HMAC-SHA256</tt> (cf. <xref target="hmac"/>).</t> + <artwork><![CDATA[ HKDF(salt, IKM, info, L) -> OKM Inputs: @@ -179,21 +167,17 @@ Inputs: Output: OKM output keying material (of L octets) -]]></artwork></figure> - -<t>The output OKM is calculated as follows:</t> - -<figure><artwork><![CDATA[ +]]></artwork> + <t>The output OKM is calculated as follows:</t> + <artwork><![CDATA[ PRK = HKDF-Extract(salt, IKM) with Hash = SHA-512 (HashLen = 64) OKM = HKDF-Expand(PRK, info, L) with Hash = SHA-256 (HashLen = 32) -]]></artwork></figure> - -</section> -<section anchor="hkdf-mod"><name>HKDF-Mod</name> - -<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> - -<figure><artwork><![CDATA[ +]]></artwork> + </section> + <section anchor="hkdf-mod"> + <name>HKDF-Mod</name> + <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> + <artwork><![CDATA[ HKDF-Mod(N, salt, IKM, info) -> OKM Inputs: @@ -206,33 +190,30 @@ Inputs: Output: OKM output keying material (smaller than N) -]]></artwork></figure> - -<t>The final output <spanx style="verb">OKM</spanx> is determined deterministically based on a counter initialized at zero.</t> - -<figure><artwork><![CDATA[ +]]></artwork> + <t>The final output <tt>OKM</tt> is determined deterministically based on a counter initialized at zero.</t> + <artwork><![CDATA[ counter = 0 do until OKM < N: x = HKDF(salt, IKM, info | uint16(counter), bytes(N)) OKM = uint(bits(N), x) counter += 1 -]]></artwork></figure> - -</section> -</section> -<section anchor="non-blind-signatures"><name>Non-Blind Signatures</name> - -<section anchor="ed25519"><name>Ed25519</name> - -</section> -</section> -<section anchor="blind-signatures"><name>Blind Signatures</name> - -<section anchor="rsa-fdh"><name>RSA-FDH</name> - -<section anchor="supporting-functions"><name>Supporting Functions</name> - -<figure><artwork><![CDATA[ +]]></artwork> + </section> + </section> + <section anchor="non-blind-signatures"> + <name>Non-Blind Signatures</name> + <section anchor="ed25519"> + <name>Ed25519</name> + </section> + </section> + <section anchor="blind-signatures"> + <name>Blind Signatures</name> + <section anchor="rsa-fdh"> + <name>RSA-FDH</name> + <section anchor="supporting-functions"> + <name>Supporting Functions</name> + <artwork><![CDATA[ RSA-FDH(msg, pubkey) -> fdh Inputs: @@ -241,21 +222,17 @@ Inputs: Output: fdh full-domain hash of msg over pubkey.N -]]></artwork></figure> - -<t><spanx style="verb">fdh</spanx> is calculated based on HKDF-Mod from <xref target="hkdf-mod"/> as follows:</t> - -<figure><artwork><![CDATA[ +]]></artwork> + <t><tt>fdh</tt> is calculated based on HKDF-Mod from <xref target="hkdf-mod"/> as follows:</t> + <artwork><![CDATA[ info = "RSA-FDA FTpsW!" salt = uint16(bytes(pubkey.N)) | uint16(bytes(pubkey.e)) | pubkey.N | pubkey.e fdh = HKDF-Mod(pubkey.N, salt, msg, info) -]]></artwork></figure> - -<t>The resulting <spanx style="verb">fdh</spanx> can be used to test against a malicious RSA pubkey -by verifying that the greatest common denominator (gcd) of <spanx style="verb">fdh</spanx> and <spanx style="verb">pubkey.N</spanx> is 1.</t> - -<figure><artwork><![CDATA[ +]]></artwork> + <t>The resulting <tt>fdh</tt> can be used to test against a malicious RSA pubkey +by verifying that the greatest common denominator (gcd) of <tt>fdh</tt> and <tt>pubkey.N</tt> is 1.</t> + <artwork><![CDATA[ RSA-FDH-Derive(bks, pubkey) -> out Inputs: @@ -264,20 +241,17 @@ Inputs: Output: out full-domain hash of bks over pubkey.N -]]></artwork></figure> - -<t><spanx style="verb">out</spanx> is calculated based on HKDF-Mod from <xref target="hkdf-mod"/> as follows:</t> - -<figure><artwork><![CDATA[ +]]></artwork> + <t><tt>out</tt> is calculated based on HKDF-Mod from <xref target="hkdf-mod"/> as follows:</t> + <artwork><![CDATA[ info = "Blinding KDF" salt = "Blinding KDF extractor HMAC key" fdh = HKDF-Mod(pubkey.N, salt, bks, info) -]]></artwork></figure> - -</section> -<section anchor="blinding"><name>Blinding</name> - -<figure><artwork><![CDATA[ +]]></artwork> + </section> + <section anchor="blinding"> + <name>Blinding</name> + <artwork><![CDATA[ RSA-FDH-Blind(msg, bks, pubkey) -> out Inputs: @@ -287,21 +261,18 @@ Inputs: Output: out message blinded for pubkey -]]></artwork></figure> - -<t><spanx style="verb">out</spanx> is calculated based on RSA-FDH from <xref target="rsa-fdh"/> as follows:</t> - -<figure><artwork><![CDATA[ +]]></artwork> + <t><tt>out</tt> is calculated based on RSA-FDH from <xref target="rsa-fdh"/> as follows:</t> + <artwork><![CDATA[ data = RSA-FDH(msg, pubkey) r = RSA-FDH-Derive(bks, pubkey) r_e = r ** pubkey.e (mod pubkey.N) out = r_e * data (mod pubkey.N) -]]></artwork></figure> - -</section> -<section anchor="signing"><name>Signing</name> - -<figure><artwork><![CDATA[ +]]></artwork> + </section> + <section anchor="signing"> + <name>Signing</name> + <artwork><![CDATA[ RSA-FDH-Sign(data, privkey) -> sig Inputs: @@ -310,18 +281,15 @@ Inputs: Output: sig signature on data by privkey -]]></artwork></figure> - -<t><spanx style="verb">sig</spanx> is calculated as follows:</t> - -<figure><artwork><![CDATA[ +]]></artwork> + <t><tt>sig</tt> is calculated as follows:</t> + <artwork><![CDATA[ sig = data ** privkey.d (mod privkey.N) -]]></artwork></figure> - -</section> -<section anchor="unblinding"><name>Unblinding</name> - -<figure><artwork><![CDATA[ +]]></artwork> + </section> + <section anchor="unblinding"> + <name>Unblinding</name> + <artwork><![CDATA[ RSA-FDH-Unblind(sig, bks, pubkey) -> out Inputs: @@ -331,20 +299,17 @@ Inputs: Output: out unblinded signature -]]></artwork></figure> - -<t><spanx style="verb">out</spanx> is calculated as follows:</t> - -<figure><artwork><![CDATA[ +]]></artwork> + <t><tt>out</tt> is calculated as follows:</t> + <artwork><![CDATA[ r = RSA-FDH-Derive(bks, pubkey) r_inv = inverse of r (mod pubkey.N) out = sig * r_inv (mod pubkey.N) -]]></artwork></figure> - -</section> -<section anchor="verifying"><name>Verifying</name> - -<figure><artwork><![CDATA[ +]]></artwork> + </section> + <section anchor="verifying"> + <name>Verifying</name> + <artwork><![CDATA[ RSA-FDH-Verify(msg, sig, pubkey) -> out Inputs: @@ -354,58 +319,52 @@ Inputs: Output: out true, if sig is a valid signature -]]></artwork></figure> - -<t><spanx style="verb">out</spanx> is calculated based on RSA-FDH from <xref target="rsa-fdh"/> as follows:</t> - -<figure><artwork><![CDATA[ +]]></artwork> + <t><tt>out</tt> is calculated based on RSA-FDH from <xref target="rsa-fdh"/> as follows:</t> + <artwork><![CDATA[ data = RSA-FDH(msg, pubkey) exp = sig ** pubkey.e (mod pubkey.N) out = (data == exp) -]]></artwork></figure> - -</section> -</section> -<section anchor="clause-schnorr"><name>Clause-Schnorr</name> - -</section> -</section> -</section> -<section anchor="the-taler-crypto-protocol"><name>The Taler Crypto Protocol</name> - -<section anchor="datatypes"><name>Datatypes</name> - -<section anchor="amount"><name>Amount</name> - -<t>Amounts are represented in Taler as positive fixed-point values -consisting of <spanx style="verb">value</spanx> as the non-negative integer part of the base currency, -the <spanx style="verb">fraction</spanx> given in units of one hundred millionth (1e-8) of the base currency, -and <spanx style="verb">currency</spanx> as the 3-11 ASCII characters identifying the currency.</t> - -<t>Whenever used in the protocol, the binary representation of an <spanx style="verb">amount</spanx> is -<spanx style="verb">uint64(amount.value) | uint32(amount.fraction) | padZero(12, amount.currency)</spanx>.</t> - -</section> -<section anchor="timestamps"><name>Timestamps</name> - -<t>Absolute timestamps are represented as <spanx style="verb">uint64(x)</spanx> where <spanx style="verb">x</spanx> corresponds to -the microseconds since <spanx style="verb">1970-01-01 00:00 CEST</spanx> (the UNIX epoch). -The special value <spanx style="verb">0xFFFFFFFFFFFFFFFF</spanx> represents "never". +]]></artwork> + </section> + </section> + <section anchor="clause-schnorr"> + <name>Clause-Schnorr</name> + </section> + </section> + </section> + <section anchor="the-taler-crypto-protocol"> + <name>The Taler Crypto Protocol</name> + <section anchor="datatypes"> + <name>Datatypes</name> + <section anchor="amount"> + <name>Amount</name> + <t>Amounts are represented in Taler as positive fixed-point values +consisting of <tt>value</tt> as the non-negative integer part of the base currency, +the <tt>fraction</tt> given in units of one hundred millionth (1e-8) of the base currency, +and <tt>currency</tt> as the 3-11 ASCII characters identifying the currency.</t> + <t>Whenever used in the protocol, the binary representation of an <tt>amount</tt> is +<tt>uint64(amount.value) | uint32(amount.fraction) | padZero(12, amount.currency)</tt>.</t> + </section> + <section anchor="timestamps"> + <name>Timestamps</name> + <t>Absolute timestamps are represented as <tt>uint64(x)</tt> where <tt>x</tt> corresponds to +the microseconds since <tt>1970-01-01 00:00 CEST</tt> (the UNIX epoch). +The special value <tt>0xFFFFFFFFFFFFFFFF</tt> represents "never". <!-- // todo: check if needed and correct Relative timestamps are represented as `uint64(x)` where `x` is given in microseconds. The special value `0xFFFFFFFFFFFFFFFF` represents "forever". ---></t> - -</section> -<section anchor="signatures"><name>Signatures</name> - -<t>All messages to be signed in Taler start with a header containing their size and +--> + </t> + </section> + <section anchor="signatures"> + <name>Signatures</name> + <t>All messages to be signed in Taler start with a header containing their size and a fixed signing context (purpose) as registered by GANA in the <eref target="https://gana.gnunet.org/gnunet-signatures/gnunet_signatures.html">GNUnet Signature Purposes</eref> registry. Taler-related purposes start at 1000.</t> - -<figure><artwork><![CDATA[ + <artwork><![CDATA[ Sign-Msg(purpose, msg) -> out Inputs: @@ -414,28 +373,22 @@ Inputs: Output: out complete message (incl. header) to be signed -]]></artwork></figure> - -<t><spanx style="verb">out</spanx> is formed as follows:</t> - -<figure><artwork><![CDATA[ +]]></artwork> + <t><tt>out</tt> is formed as follows:</t> + <artwork><![CDATA[ out = uint32(len(msg)) | uint32(purpose) | msg -]]></artwork></figure> - -<t>// todo: explain persist, check, knows, sum, indexing (if left of equal sign, single entry; if not refers to whole list)</t> - -</section> -</section> -<section anchor="withdrawal"><name>Withdrawal</name> - -<t>The wallet generates <spanx style="verb">n &gt; 0</spanx> coins (<spanx style="verb">coinᵢ</spanx>) and requests <spanx style="verb">n</spanx> signatures (<spanx style="verb">blind_sigᵢ</spanx>) from the exchange, -attributing value to the coins according to <spanx style="verb">n</spanx> chosen denominations (<spanx style="verb">denomᵢ</spanx>). +]]></artwork> + <t>// todo: explain persist, check, knows, sum, indexing (if left of equal sign, single entry; if not refers to whole list)</t> + </section> + </section> + <section anchor="withdrawal"> + <name>Withdrawal</name> + <t>The wallet generates <tt>n &gt; 0</tt> coins (<tt>coinᵢ</tt>) and requests <tt>n</tt> signatures (<tt>blind_sigᵢ</tt>) from the exchange, +attributing value to the coins according to <tt>n</tt> chosen denominations (<tt>denomᵢ</tt>). The total value and withdrawal fee (defined by the exchange per denomination) must be smaller or equal to the amount stored in the single reserve used for withdrawal.</t> - -<t>// todo: extend with extra roundtrip for CBS</t> - -<figure><artwork><![CDATA[ + <t>// todo: extend with extra roundtrip for CBS</t> + <artwork><![CDATA[ wallet exchange knows denomᵢ.pub knows denomᵢ.priv | | @@ -467,23 +420,19 @@ knows denomᵢ.pub knows denomᵢ.priv +----------------------+ | | (W3) coin unblinding | | +----------------------+ | -]]></artwork></figure> - -<t>where (for RSA, without age-restriction)</t> - -<figure><artwork><![CDATA[ +]]></artwork> + <t>where (for RSA, without age-restriction)</t> + <artwork><![CDATA[ (W1) reserve key generation (wallet) reserve = EdDSA-Keygen() persist (reserve, value) -]]></artwork></figure> - -<t>The wallet derives coins and blinding secrets using a HKDF from a single master secret per withdrawal operation, +]]></artwork> + <t>The wallet derives coins and blinding secrets using a HKDF from a single master secret per withdrawal operation, together with an integer index. This is strictly speaking an implementation detail since the master secret is never revealed to any other party, and might be chosen to be implemented differently.</t> - -<figure><artwork><![CDATA[ + <artwork><![CDATA[ (W2) coin generation and blinding (wallet) master_secret = random(256) @@ -499,9 +448,8 @@ msg = Sign-Msg(WALLET_RESERVE_WITHDRAW, | SHA-512( SHA-512(~(denomᵢ.pub)) | uint32(0x1) | blind_coinᵢ ) | uint256(0x0) | uint32(0x0) | uint32(0x0) )) sig = EdDSA-Sign(reserve.priv, msg) -]]></artwork></figure> - -<figure><artwork><![CDATA[ +]]></artwork> + <artwork><![CDATA[ (E1) coin issuance and signing (exchange) denomᵢ = Denom-Lookup(coinᵢ.h_denom) @@ -513,20 +461,18 @@ check reserve.balance >= total reserve.balance -= total blind_sigᵢ = RSA-FDH-Sign(blind_coinᵢ, denomᵢ.priv) persist withdrawal -]]></artwork></figure> - -<figure><artwork><![CDATA[ +]]></artwork> + <artwork><![CDATA[ (W4) coin unblinding (wallet) coinᵢ.sig = RSA-FDH-Unblind(blind_sigᵢ, blind_secretᵢ, denomᵢ.pub) check RSA-FDH-Verify(SHA-512(coinᵢ.pub), coinᵢ.sig, denomᵢ.pub) persist (coinᵢ, blind_secretᵢ) -]]></artwork></figure> - -</section> -<section anchor="payment"><name>Payment</name> - -<figure><artwork><![CDATA[ +]]></artwork> + </section> + <section anchor="payment"> + <name>Payment</name> + <artwork><![CDATA[ wallet merchant knows merchant.pub knows merchant.priv knows valid coinᵢ knows exchange, payto @@ -567,30 +513,25 @@ knows valid coinᵢ knows exchange, payto +---------------------------+ | | (W3) payment verification | | +---------------------------+ | -]]></artwork></figure> - -<t>where (without age restriction, policy and wallet data hash)</t> - -<figure><artwork><![CDATA[ +]]></artwork> + <t>where (without age restriction, policy and wallet data hash)</t> + <artwork><![CDATA[ (M1) order generation (merchant) wire_salt = random(128) persist order = (id, price, info, token?, wire_salt) -]]></artwork></figure> - -<figure><artwork><![CDATA[ +]]></artwork> + <artwork><![CDATA[ (W1) nonce generation (wallet) nonce = EdDSA-Keygen() persist nonce.priv -]]></artwork></figure> - -<t>Note that the private key of <spanx style="verb">nonce</spanx> is currently not used anywhere in the protocol. +]]></artwork> + <t>Note that the private key of <tt>nonce</tt> is currently not used anywhere in the protocol. However, it could be used in the future to prove ownership of an order transaction, enabling use-cases such as "unclaiming" or transferring an order to another person, or proving the payment without resorting to the individual coins.</t> - -<figure><artwork><![CDATA[ + <artwork><![CDATA[ (M2) contract generation (merchant) h_wire = HKDF(wire_salt, payto, "merchant-wire-signature", 64) @@ -602,9 +543,8 @@ persist contract h_contract = SHA-512(canonicalJSON(contract)) msg = Sign-Msg(MERCHANT_CONTRACT, h_contract) sig = EdDSA-Sign(merchant.priv, msg) -]]></artwork></figure> - -<figure><artwork><![CDATA[ +]]></artwork> + <artwork><![CDATA[ (W2) payment preparation (wallet) check EdDSA-Verify(merchant.pub, msg, sig) @@ -621,27 +561,26 @@ msgᵢ = Sign-Msg(WALLET_COIN_DEPOSIT, sigᵢ = EdDSA-Sign(coinᵢ.priv, msgᵢ) depositᵢ = (coinᵢ.{pub,sig,h_denom}, contributionᵢ, sigᵢ) persist (contract, ~sig, ~deposit) -]]></artwork></figure> - -<figure><artwork><![CDATA[ +]]></artwork> + <t>// TODO: explain CoinSelection +// TODO: maybe better {sigᵢ} instead of ~sig?</t> + <artwork><![CDATA[ (M3) deposit check (merchant) check sum(depositᵢ.fraction) == contract.price check Deposit(deposit)ᵢ msg = Sign-Msg(MERCHANT_PAYMENT_OK, h_contract) sig = EdDSA-Sign(merchant.priv, msg) -]]></artwork></figure> - -<figure><artwork><![CDATA[ +]]></artwork> + <artwork><![CDATA[ (W3) payment verification (wallet) check EdDSA-Verify(merchant.pub, msg, sig) -]]></artwork></figure> - -</section> -<section anchor="deposit"><name>Deposit</name> - -<figure><artwork><![CDATA[ +]]></artwork> + </section> + <section anchor="deposit"> + <name>Deposit</name> + <artwork><![CDATA[ merchant/wallet exchange knows exchange.pub knows exchange.priv knows merchant.pub knows *denom.pub @@ -669,280 +608,251 @@ knows contract, *deposit from Payment |<----- sig3, exchange_timestamp --------| | | check EdDSA-Verify(exchange.pub, msg3, sig3) | -]]></artwork></figure> - -<t>where <spanx style="verb">msg3</spanx> is formed as follows:</t> - -<figure><artwork><![CDATA[ +]]></artwork> + <t>where <tt>msg3</tt> is formed as follows:</t> + <artwork><![CDATA[ msg3 = Sign-Msg(EXCHANGE_CONFIRM_DEPOSIT, ( h_contract | contract.h_wire | uint512(0x0) | exchange_timestamp | contract.wire_deadline | contract.refund_deadline | sum(*deposit.fraction - *denom.fee_deposit) | SHA-512(*deposit.sig1) | merchant.pub )) -]]></artwork></figure> - -</section> -</section> -<section anchor="security-considerations"><name>Security Considerations</name> - -<t>[ TBD ]</t> - -</section> -<section anchor="iana-considerations"><name>IANA Considerations</name> - -<t>None.</t> - -</section> - - +]]></artwork> + </section> + </section> + <section anchor="security-considerations"> + <name>Security Considerations</name> + <t>[ TBD ]</t> + </section> + <section anchor="iana-considerations"> + <name>IANA Considerations</name> + <t>None.</t> + </section> </middle> - <back> - - - - <references title='Normative References' anchor="sec-normative-references"> - - - -<reference anchor="RFC20"> - <front> - <title>ASCII format for network interchange</title> - <author fullname="V.G. Cerf" initials="V.G." surname="Cerf"/> - <date month="October" year="1969"/> - </front> - <seriesInfo name="STD" value="80"/> - <seriesInfo name="RFC" value="20"/> - <seriesInfo name="DOI" value="10.17487/RFC0020"/> -</reference> - -<reference anchor="RFC2104"> - <front> - <title>HMAC: Keyed-Hashing for Message Authentication</title> - <author fullname="H. Krawczyk" initials="H." surname="Krawczyk"/> - <author fullname="M. Bellare" initials="M." surname="Bellare"/> - <author fullname="R. Canetti" initials="R." surname="Canetti"/> - <date month="February" year="1997"/> - <abstract> - <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> - </abstract> - </front> - <seriesInfo name="RFC" value="2104"/> - <seriesInfo name="DOI" value="10.17487/RFC2104"/> -</reference> - -<reference anchor="RFC5869"> - <front> - <title>HMAC-based Extract-and-Expand Key Derivation Function (HKDF)</title> - <author fullname="H. Krawczyk" initials="H." surname="Krawczyk"/> - <author fullname="P. Eronen" initials="P." surname="Eronen"/> - <date month="May" year="2010"/> - <abstract> - <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> - </abstract> - </front> - <seriesInfo name="RFC" value="5869"/> - <seriesInfo name="DOI" value="10.17487/RFC5869"/> -</reference> - -<reference anchor="RFC6234"> - <front> - <title>US Secure Hash Algorithms (SHA and SHA-based HMAC and HKDF)</title> - <author fullname="D. Eastlake 3rd" initials="D." surname="Eastlake 3rd"/> - <author fullname="T. Hansen" initials="T." surname="Hansen"/> - <date month="May" year="2011"/> - <abstract> - <t>Federal Information Processing Standard, FIPS</t> - </abstract> - </front> - <seriesInfo name="RFC" value="6234"/> - <seriesInfo name="DOI" value="10.17487/RFC6234"/> -</reference> - -<reference anchor="HKDF"> - <front> - <title>Cryptographic Extraction and Key Derivation: The HKDF Scheme</title> - <author fullname="Hugo Krawczyk" initials="H." surname="Krawczyk"> - <organization/> - </author> - <date year="2010"/> - </front> - <seriesInfo name="Lecture Notes in Computer Science" value="pp. 631-648"/> - <seriesInfo name="DOI" value="10.1007/978-3-642-14623-7_34"/> - <seriesInfo name="ISBN" value="[&quot;9783642146220&quot;, &quot;9783642146237&quot;]"/> -<refcontent>Springer Berlin Heidelberg</refcontent></reference> - -<reference anchor="SHS"> - <front> - <title>Secure hash standard</title> - <author> - <organization/> - </author> - <date year="2015"/> - </front> - <seriesInfo name="DOI" value="10.6028/nist.fips.180-4"/> -<refcontent>National Institute of Standards and Technology (U.S.)</refcontent></reference> - - - - + <references anchor="sec-normative-references"> + <name>Normative References</name> + <reference anchor="RFC20"> + <front> + <title>ASCII format for network interchange</title> + <author fullname="V.G. Cerf" initials="V.G." surname="Cerf"/> + <date month="October" year="1969"/> + </front> + <seriesInfo name="STD" value="80"/> + <seriesInfo name="RFC" value="20"/> + <seriesInfo name="DOI" value="10.17487/RFC0020"/> + </reference> + <reference anchor="RFC2104"> + <front> + <title>HMAC: Keyed-Hashing for Message Authentication</title> + <author fullname="H. Krawczyk" initials="H." surname="Krawczyk"/> + <author fullname="M. Bellare" initials="M." surname="Bellare"/> + <author fullname="R. Canetti" initials="R." surname="Canetti"/> + <date month="February" year="1997"/> + <abstract> + <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> + </abstract> + </front> + <seriesInfo name="RFC" value="2104"/> + <seriesInfo name="DOI" value="10.17487/RFC2104"/> + </reference> + <reference anchor="RFC5869"> + <front> + <title>HMAC-based Extract-and-Expand Key Derivation Function (HKDF)</title> + <author fullname="H. Krawczyk" initials="H." surname="Krawczyk"/> + <author fullname="P. Eronen" initials="P." surname="Eronen"/> + <date month="May" year="2010"/> + <abstract> + <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> + </abstract> + </front> + <seriesInfo name="RFC" value="5869"/> + <seriesInfo name="DOI" value="10.17487/RFC5869"/> + </reference> + <reference anchor="RFC6234"> + <front> + <title>US Secure Hash Algorithms (SHA and SHA-based HMAC and HKDF)</title> + <author fullname="D. Eastlake 3rd" initials="D." surname="Eastlake 3rd"/> + <author fullname="T. Hansen" initials="T." surname="Hansen"/> + <date month="May" year="2011"/> + <abstract> + <t>Federal Information Processing Standard, FIPS</t> + </abstract> + </front> + <seriesInfo name="RFC" value="6234"/> + <seriesInfo name="DOI" value="10.17487/RFC6234"/> + </reference> + <reference anchor="HKDF"> + <front> + <title>Cryptographic Extraction and Key Derivation: The HKDF Scheme</title> + <author fullname="Hugo Krawczyk" initials="H." surname="Krawczyk"> + <organization/> + </author> + <date year="2010"/> + </front> + <seriesInfo name="Lecture Notes in Computer Science" value="pp. 631-648"/> + <seriesInfo name="DOI" value="10.1007/978-3-642-14623-7_34"/> + <seriesInfo name="ISBN" value="[&quot;9783642146220&quot;, &quot;9783642146237&quot;]"/> + <refcontent>Springer Berlin Heidelberg</refcontent> + </reference> + <reference anchor="SHS"> + <front> + <title>Secure hash standard</title> + <author> + <organization/> + </author> + <date year="2015"/> + </front> + <seriesInfo name="DOI" value="10.6028/nist.fips.180-4"/> + <refcontent>National Institute of Standards and Technology (U.S.)</refcontent> + </reference> </references> - - - - -<?line 656?> - -<section anchor="change-log"><name>Change log</name> - -</section> -<section numbered="false" anchor="acknowledgments"><name>Acknowledgments</name> - -<t>[ TBD ]</t> - -<t>This work was supported in part by the German Federal Ministry of + <?line 659?> + +<section anchor="change-log"> + <name>Change log</name> + </section> + <section numbered="false" anchor="acknowledgments"> + <name>Acknowledgments</name> + <t>[ TBD ]</t> + <t>This work was supported in part by the German Federal Ministry of Education and Research (BMBF) within the project Concrete Contracts.</t> - -</section> - - + </section> </back> - -<!-- ##markdown-source: -H4sIAAAAAAAAA80823bbOJLv/AqM80Imom523Imm1bOOL7E3sZy1ncnMZrIW -REIS1xSp4SW2OrE/Zv9h3/Ztv2T/ZKsKAAlSku3cutsnJ6bAQqFQ9yrAcl3X -+thjm5aVBVkoemzjfCrYy8Fbds5DkbA3SZzFXhxuWH7sRXwGEH7Cx5k7yUWW -etP4ys0Q0J0rQMvjmZjEyaLHgmgcW1YwT3osS/I067bbz9td6ypOLidJnM8R -whdzAf9FmZVmieCz6tilWAC037MYcxmtQ09esphn8STh8+mCBoTH0yk9zfli -BjNTy3r0UUS56FmPGEvEPO6xaZbN016rNQmy5iTKI5E142TSClO/DYQ1YbiF -wCHQn2YlOLxfAd6yLJ5n0zgB2lxYmTHJnOPgMg55wF7+7/9I9tA7mNhj52/3 -2F4iUtgZexsFH0WSBtmCxWN2LrxpFIfxZEHQfDRKxEecoOFpGBkkgLBDEc6m -cZj9CgNN1mnTSw9Q9SrgXuwDPXtuu9Pefq5G8ihDwbwUyYxHcjEx40HYYzNJ -d7MQ679kuetLdE1fWFYUw5wMqEZhnB7sdtv6odPeUo9Pn20/V4/b3U0aPXy1 -dwBUnBw1O2341/6p9fynZ+6mu73VdTtbAOX+dLG5BYBnh2cF3Ha7+6w1ODo7 -bx4cvTlrdp613S1QJFCnggbLcl0XOAU84F5mWf94z85fvGP/+CBfzALfD4Hq -R+wIthz7uZcFcVQBeyGueCJYNuUZ/BekDBQ8R91h8JxmQRgy1FQ3iFC3J8CK -lPHIZzO+AE5GGQ8iJpIkTtKm9TYVDNAs4jxh8VXEkiC9/BOuPogzLld22XCD -j7yNIQOOxqBisKhgYZCJhIco2yCasCFADJmIUHY+4ynbOds9OmLvid8fEAdn -n9moigOIQZuLaCFUJ86ugmzKRggfisjmTm1REU3gPdA/WuAYTMFh/KAJ4Th3 -zv1/F0lsLxqsjqIC22C/ApgL4Eh1FpuLAO6FXAYxjoIsta+dYWtIQ/hYQTsL + <!-- ##markdown-source: +H4sIAAAAAAAAA80823bbOJLv/Aq080Imom523IkmSq/jS+xNLGdtZzKzmawF +kZDENUVqeImtTuyP2X/Yt33bL9k/2aoCQIK0ZDvXbp2cWAILhULdqwDJdV3r +Y4+tW1YWZKHosbXTqWAvB2/ZKQ9Fwt4kcRZ7cbhm+bEX8RlA+AkfZ+4kF1nq +TeMLN0NAd64ALY9nYhInix4LonFsWcE86bEsydOs224/bXetizg5nyRxPkcI +X8wF/BdlVpolgs+qY+diAdB+z2LMZbQOvfOSxTyLJwmfTxc0IDyeTundnC9m +MDO1rAcfRZSLnvWAsUTM4x6bZtk87bVakyBrTqI8ElkzTiatMPXbQFgThlsI +HAL9aVaCw/Ml4C3L4nk2jROgzYWVGZPMOQzO45AH7OX//o9kDz2DiT12+naH +7SQihZ2xt1HwUSRpkC1YPGanwptGcRhPFgTNR6NEfMQJGp6GkUECCNsX4Wwa +h9nvMNBknTY99ABVrwLuxT7Qs+O2O+3Np2okjzIUzEuRzHgkFxMzHoQ9NpN0 +Nwux/kuWu75E1/SFZUUxzMmAahTG8d52t63fdNob6u3jJ5tP1dvN7jqN7r/a +2QMqjg6anTb8a//aevrrE3fd3dzoup0NgHJ/PVvfAMCT/ZMCbrPdfdIaHJyc +NvcO3pw0O0/a7gYoEqhTQYNlua4LnAIecC+zrH+8Z6cv3rF/fJAPZoHvh0D1 +A3YAW4793MuCOKqAvRAXPBEsm/IM/gtSBgqeo+4weJ9mQRgy1FQ3iFC3J8CK +lPHIZzO+AE5GGQ8iJpIkTtKm9TYVDNAs4jxh8UXEkiA9/wVXH8QZlyu7bLjG +R97akAFHY1AxWFSwMMhEwkOUbRBN2BAghkxEKDuf8ZRtnWwfHLD3xO8PiIOz +z2xUxQHEoM1FtBCqE2cXQTZlI4QPRWRzp7aoiCbwHOgfLXAMpuAwftCEcJw7 +5/6/iyS2Fw1WR1GBbbDfAcwFcKQ6i81FAPdCLoMYR0GW2pfOsDWkIXxbQTsL omAG7Ijy2QicD0zGGS1JZiQ8kAFPFrgEmDRIBKVF8/IwC+ahYDDoBSnyIYjA -DQGOa1w3h0+4jfp6w8UQCOVpxtJgEgXjwOOAEdfUTNFohtelXIBx4A1QOSQf -wEMBhD0KJgDiBzxy9JqdbblbfN7sls/bW+Vz96kB9LRDUKiC4p958BFcHm4x -VlvobNMeJKy92TU/bW+ZnwCr+RHw0scGMC6dCw+NKFwgmQnodDyzFwZnOJOD -4YJNRAT6mcGmU6AHGCCURIFFUh0fsxGzZ7HPBoChRSOVoYp4pZiAy6SqLSau -53EEOwwK3V0vSaQL7W/UYIA7D2M2QAvbLWNB4EG4CmYBbg4DQP3lIQQJdpBH -5AsI4BG4nR0XeMU+PUqnHB5uLOv29tZSw/YsnTjM/YVNMb5YR9E8z3rkNuEF -/gLiYIjNUDEnxBul96/Zz6z7H9sdFnuZwHB0kmfFZMRGSNQ0P5hAyMHZ4+Aa -eK1wIL2vIVj02WZX40HirCEiICVBrsaEGWfrzYDjmINGngm5U7bV7DTYU/xv -G/9DLm43uzjjvXLVH5olO0BXJDvgwWAHquY3sqPTffp9+LG99WB+4G6W+dFF -fnSRH5uaH1t38IO4akMSQ57W18NOwSeX3lW59T0U6LtxrKZB5yWfFPO8OEHX -EEd+ql34OEgAZzFTu8Rl/vpiHETSMX76pBTnpieZkYnZHNY3Ncgi6vsMX71v -9zY7HyRRECzNeBzP0fWgB/CD8RgdwDiJZxpTSym6sfZ7yCE+4IN03OAHIJTQ -WuBHcwEiRZ9wrFi2A+kbuh7ljHbBtSufcHi8swuSnc64liiOuMhMGzLSBhB+ -nZFUgRUglzkikHI5VHLxKo6HaBgrxyODs2JiVU4VBYGVSEFS4SUio4+ldvBM -xS09EyGRrFKlfJ5xygYScNYYNeXUqh4BGUz9VjKtUSTtC16TeXk89PKQTKDG -epUIflBMfgXU7okEAhhtueZ0MSlEBl/64xupi7gcYFozjdk4w2F5KleTpUmA -+Rh8TDNuRpD3KhH9YBGjIU4r/cFIWpEEKFSckLLsX1MaSZ5g/3qOv9JMzHGT -aT5B01LbRDo+9Kwh/nbVrCHSlbIhKQloJygnxNmraQBRTAMiyjocKPCQ2d64 -CUZDunbjNJW6wSQ75WHWYEevjhtUSDXYa1K5k1fHSk1SKUKEIxGSGmIuiQOk -8czmLIojV6mQjOrylfNnmlz+BGMAzSDsxh8DSHJgUZkIC0o/uE72gMHgfDHf -g7QX5wGBhh8DLUUoyNJBijy05JtxXCEQs2dUVWQzn5f5ACYmmIOxItOPoxqV -NiRobATJtkw5lbJK2hyCfa0gy/xT6XaNNBSn8oi1JX7us+7Tp4/B7/XZs852 -26mazIna8Dq8Niz5WqF2lrwtzl4ypHEchvFVqjzmm9NXsLKpYaUuONJ7HEoH -qv2vbUZGx8I1CgSoeTagNLSojoKCmxkqFNnaVN3j2Id6iaP1xdK7kgVX3D4Z -801Duu7C14Ha5UlEhopUkXNHrYIkH00YPkcgywkkbNFdSfzAMAykxh40WM0+ -VhvHQEt1PfKKEf3eVvQAM/oN7OjL9L0izIGh8qAd8F6nGYCHYogvYOKMFEc/ -BimG4RDqjZFWMi67FejmZSAPfkVbyYhepQ0aos/alh8z+BCERO7PbCBpv1Z2 -UHemUESr8kzhcBqySLUHjlPsuk9ANhWtAwfrp7KNAss+6bOONhQo9CP3RRiA -JM6gkuSg9Tqb2PfBm3SeE9RqiNOzHfdg7xAiYpJyd+xPb2gcss98Po+TDNlt -RFBcUk3BdKrB5vkIhEIGAJOrBqDTTJUo0piEZ7guPoPeUHYB6pSiJKR+Uo2V -p2BBqF4KTNdrTFR1BJalVcZ5GLpgHdgboVCLiICC+CPwSy7bHKicAubUc4pC -+trOZcYnnYsLFN3cLLtLkmefbUiW7LCD83n67k8bFhlwX8tZSleT4DilBlTe -CCV+eK1hy0dh4T77BXUFOu2MSBrkjEojACmj68HmDu1YGR6lMphnY9rOJxzT -GFB6MKXAC2LguxIO4LdGCwb8C8Zkdyo/FmySCOpUgtxmM0ySodAGW+IZ5DT2 -xPMdZL5cEyU41MQS0zvNih65lHQJe3SZVtSJ8ltTnQCA2DNCRUZyUHGUYzRr -F7Pg+DEqpzPXVSqHVK5SuRVp7Dep3AvNBZhbKFxlFMinCA4yoaoCqNm4T4tI -CIYWkSvQSKtio1HpBO4V3SpP8McTpy5oiSKQDGboygzul6F2pEqE2puukCAV -R322yo1aSflilV1YyYUAiAT7XNoxyHZX4V0s3A2AAOBjWYfV3pdyxViwJFYc -tHEeLArra5GmwaQqUkKtf4MzAb+CfUzMO3iZPFXis8IHJkFylJ+kHKnsEvcL -UsEVkvSrkgQKmPotoxxKhigEP6YWVLIEkBVlZVVSiK4v5yPDFfm+4qjejcnS -t9FopbGocRswPsBc9DZoTrmZP6jZ5JE2mJLSu0r3Ko/v1/gg+ggw8L9IUupS -JatVHrn2mEn4tTr/Vx3MqvKRw9IWSUZf6s1WaN5Y85zCAUz6wXLIklw0sApA -WrBBgXVC8CCpfGcvBpRqedznp2yJp4+7M0q/3ZBDluKe4dlkkmCvHfMZ2XuR -jfXidJiS2z3Aki3mOqvdmWGebFnyN7AiEeWpjdnHwe5snFLXXnYv3XkMvktW -WKlVlcqQRoc4CZMgrMsiMaFDwcLhzXmSFYdawFXm5UkiIm/RsOjQZ4wRGXLp -oSo8gZI8Umc+IF02zSM/AQpnQRgCGJiy3RHuM2cNTsqu9MeCsk2301HHd96U -44rYwQzwWLvI5EoskI69m4pIoJbqLhe+16fqDbkwpHfJouRieeIXsSEnPqNW -WfqMSQ41ZamqMt7Nrh7WbMA3+qgPj4nUa02aM1S98PMAjC3jszkIeGeUxmGO -7dpicEnAwAjjsItdTQUA4DlatdVsyYM/D2ph4dFYGuA507Dz/Ke22+7AP9Zu -99pttrt/dj5kNsK/HRz9jYl57E2dJqXZVPNCtSkr9mH7+qD2MyxpS9kGcXqj -af38J9e1Wi0gw497ICjhXVINLwQdwIJkiVgvs05FKLXsa3YMll6omrnVr6Id -UiJFvev+oo4pjIpyJwy1V0wrSUFpcUA+WAi1gTibCo7Hl+pIWylmAEBQcSMH -LK7OFFKZqhRtB0hcEzBc0CzYdyImYKQCzQbC/MudwY5SYev9y8HbCAJjQSN7 -I+elH+ziSgaPuHnJQj66hddM1chFOdKcZrMQQhOtmyyacmtuIqQ3VbSlaq9Q -M3Xa7baqepAU9zid6B1Q5bY6zigII6bokeqmYQHc9KrYJBkGDs0W117YVAx3 -KrJZHU2gspuHAqxMY7LBMtZhqAYWbPysCvXS4ytHgJcDcOeGbyhk+pmiJSEt -7APiQ4h11hyvrqRQqpDBNNhlBAtA0M5nDbq+c41qYgeYCY3JE4t/5thSA0Ix -tEeTENJHvIryZ90wSwQd8MCGrqZxiPci0syhqPIOtNRP+BUPZT19hclsVhxM -g8VF7BfWRq8CNTSzh/j7//77v4YOmW+Cx9ZphmDDUogIRwkTKpQEpmiLrgWE -BInyRIBjz7IkGOUUeqRtqoMxuRT3wDdQ+ofn84DemwLnjEKcjhjsIX2mRaS5 -Z3FWGDuSeFXskI0FyFi3VcGOTHroCNPE7VizHMp/1ACV4UOtJDmt6JSeHEwg -TsqQoviP7iT5qBoRWGWVZDQrIgfVlTTKWpYlgNMHxsxp1u6LM6lYZndRyeje -H701ixSIaUY1IUFZN6UOCclqrbUJmvvAn8/WE/eunyd3zPzM7Hcdp+Aipo9K -JTEkryfhW9b8+n3WB4wFmT3i0SUkrjxKx+hUjHe/rFjTTvPRf0JA7Om9o7R0 -0tBTbfHvS+1quLv56D55IJrP2psxu7IhnTT9ttSsoO8ehVmvNlJJuw65K1M7 -6RaNLl1XEfIta379PusD1dVYSzsoVn2xSknhpyrNW1uFheb0gpyH07if3lsZ -InAmVaRt5wftdDXcvTJ4uIrb+x2lBkGa5hzTax6VGd1vTtEKGpdm/mwK374t -wrVTk/+3CGLNhtY74WImmtam4mke3WlN321NSsZkUWFj7IW6v0GRGZM6SA8h -+cUTPFnUyah8V5CyZZgGSA3QZ/v+3tmO+0osAM52rLpr1G6xPN5Qod6nrlGq -MyPTwci+WAqJBl0WlUfHlG1xnYvMOGbRuoOGeY6RExXXgKB6jycCUphElS5l -i5OSTsyuIPOl27vIhXCBlRW/pGUBFnPpWVE1+wLKnVDVmlSCVogI8L4pVuNY -a0FlQYc1PFqwmAjAFoMq/WfBZEpZmEr/ZFJerIbHnPr6SbhoarHc55ZL4Ui6 -LhRdfXX+jBc8S/lUYCxEDM/CB3+nD0BVeh+A36sAN9iGvL9fctzF+a5fXMPZ -aNCtAmWANEsiNtd5v9ntfbC0k8W0rA7Q2+waAJDhaW17KbI3+cg25zpWzV0b -N8jUTtpG0dLBZzN71NQqLEZ7U56YaFwGOXgCXN1ho4YSy7o+K2rHdzuvX++f -X5zun+2f/nX/4t3R+eHe6c67BrkjG4shu5hfdGAqo5DtX2i2y2PHz8Uui4db -u0KFsev2Ne27ulONR98sbl+3K1OWPjmOarFLYdDRQxE6QRSyNpYGT6p7dyix -dU4PmqsJB+R7+Oi+juPLfL4Uii3Zd6mk/5jnS5PA8tBQTqhBA6hm1BxJtOoc -VyK+biNr7NrHvfr7LvYEsjxl8SVWTIhf9nssWZn1SUq3dek57En9RUWAtYWa -Ix4Sd37py4rPqr9w9QuzEjVUlURRkW6jWviU9l/yxxDUu63l+FS6FS0EKfz6 -GYlJ0r2GIfdda+OvNjFj1TqWItYUm60tW7Sm2Rv5Rz5fX3jORIJamqnCU39c -X3jW4bDslGOyv6/N767ZRWMB/0gpi3+3/PEL0sZjsHX51w1mcfsbrb+CorVJ -IrP/7dTFK7ysxQYHu/D/29MjI1O8i2abdtj8FPiNLL4U0V9uvleev5YD985U -7YUoRkfxoMbCt69ZH7hnwh0ztVBaxNm09UlyOPBvWl7Ig5mSy5rKTf7YtHfp -y6VY/jDV15cYEOV5kbxd/B1t6AeZEVmSpleGz0q19SOM4T7dLNoY6k878QYn -pN8PsIdvWbM+8MBtfpkxwI4K9t5pDPhj3/qCzkkdVgf8fYzhS8wASmVFvTpk -+01WXkHLnW0Gqf8regw/TvXv1MOizaBVn64B6mu+dxHwLWuabQaju8CM7gKk -MHEYeAt5fqFaAHiJAG/g6dbDyuTB1jkUQF1BIn+hbs2pqrbTfVZmgnJyn9kQ -mfGqjyf0JXYZELD5oTCYBcrKwFkmvvLV2laHCjuY4C39UZKoXJLC2wgELW9y -0HE5Nh2woKBTFR4tJBtrh/lN6zC+wuYCXQ/34jz0iyuhCnSc01ljFtNVcoF/ -VAz0TYO5Ou2XrKGmvTzEb1gi4pgwTxCP63E6+8y9KR4BbuQRxV14u4Elj272 -J6o1orBhg0O1N2AxxImX7/Aqu7qtoNVQawVohLqerA6csMr4GPg5XU4PolS3 -O9aFQVMbphcoTd2vKCSrsuUG29CwLr4rz4ZVe6K4Vl4e0OMfu45zKCF8wX1g -jVAKoz9aBUl9MwmUmkaKpvLBhpG7SzIbD19F10d6saZciVDjpRt6KEhpavUs -0p9CMzUIcMogvKizQHYR3qL/17OTQRHDnaW2xfH+6e7hzuD8YvdkcH66s3uO -WyrAl3sBlZpnqRmwLi4bdeZynW6WW8uF+mpOWOcneyc95sf5KAT1Jkh5HkmX -fmngL9ZtKkL5R54wbxc08Ex/LjjS/FTIkgQNyb5EjUfrORQQxzy53AuSbMHQ -di17qfZuSBLpZDjGVw62DPRC8BlZLkv5erNo9+RocLG3/+bk7OhcN4oMaVbb -NkYnBwWsejfFPpS9fGa1doqaVsAVimoO1lTWnFPuiz1hlVaHiuAKeNUrvDVg -1tI16mWvSbLGUDGz80f6QMW+QimhC5hPqDPYPVC7vVmSBikTYTA6CjqjvaXG -Q5FJGZq8nKKYzkmOyO6dJsu4QNXvl6wlrVIT9iSwnuQo5Vhpj292/n68D79P -Xn2bRa5LF77KJHXHRW2k0nHRc1oP6brUjvr1x/s6LiVc2XF5aLfmMSkIuVA5 -oAKJEVpgj12T2wqw1JfHWiXowEL3neop091bNwDvPIhvjXjmTV29opmwrTyI -Lz1aGYsqkadRs/KbFYSXe2+wqhJI3qwjnGluag6ZydidW/56Zq2DfKyPCCpd -Zk1YE11H2Wt+KFJpJKUO1TrSCnnRjn4w2pr7XpfufDXb1M892dIXcqHiKyp8 -1f6iQwrT+WLMa7rG9TWcb2VIBWHZfZat5y+jGcWP18lT/JYqvMX+0Ok6Hmnd -SQReIMMDueTSRWwP9ywpkOLnId5FNi7vPHi6dqsXZXKAedaV/XBeAA83q3Gp -4qtJKTYfjq7+s65Qp3UbqzbwPQr1FZHRjFRyU6Tpm051plE0DxHozkuYCGDm -APt/wxTg5T7m5AdHp8d3pojLCaCZY6nkbAV/jJnVKkjOuCc1xNSn8Kg68WGu -dpBGDlg/ySxmkX+oZ4iOzjHw21nyBL8QbRcv/PuqREzVd3bt0Xd2PWJHeLO4 -DjGII/x2D1SPEfcu6WuB5J3JMJ7gpx0PvXco/In8crhPPfkNU8Lvb4x5mIqN -m8o6dJGAvuDpir4Cgv4MV1bn9McF6mqm/B41diB8+hKvY/pL5gQ7A9a+n3vl -sf6pSAWHXTP7xfGLA/kX+GVTAK/T4Z7wnEvgAwkCiuf/B1xTDYydTwAA +DQGOS1w3h0+4jfp6w8UQCOVpxtJgEgXjwOOAEdfUTNFohpelXIBx4A1QOSQf +wEMBhD0KJgDiBzxy9JqdTblbfL/eLd9vbpTvu48NoMcdgkIVFP/Mg4/g8nCL +sdpCZ5P2IGHt9a75aXPD/ARYzY+Alz42gHHpXHhoROECyUxAp+OZvTA4w5kc +DBdsIiLQzww2nQI9wAChJAoskur4kI2YPYt9NgAMLRqpDFXEK8UEXCZVbTFx +OY8j2GFQ6O5qSSJdaH+jBgPceRizAVrYdhkLAg/CVTALcHMYAOoP9yFIsL08 +Il9AAA/A7Wy5wCv26UE65fDmyrKur68tNWzP0onD3OdsivHFOojmedYjtwkP +8A8QB0Nshoo5Id4ovX/NnrHuf2x2WOxlAsPRUZ4VkxEbIVHT/GACIQdnj4NL +4LXCgfS+hmDRZ+tdjQeJs4aIgJQEuRoTZpytNwOOYw4aeSLkTtlGs9Ngj/G/ +TfwPubjZ7OKM98pVf2iW7ABdkeyANwY7UDW/kR2d7uPvw4/NjXvzA3dzkx9d +5EcX+bGu+bFxCz+IqzYkMeRpfT3sFHxy6VmVW99Dgb4bx2oadFrySTHPixN0 +DXHkp9qFj4MEcBYztUu8yV9fjINIOsZPn5TiXPUkMzIxm8P6pgZZRH2f4aP3 +7d5654MkCoKlGY/jOboe9AB+MB6jAxgn8UxjailFN9Z+DznEB3wjHTf4AQgl +tBb40VyASNEnHCqWbUH6hq5HOaNtcO3KJ+wfbm2DZKczriWKIy4y04aMtAGE +X2YkVWAFyGWOCKRc9pVcvIrjIRrGyvHI4KyYWJVTRUFgJVKQVHiJyOhjqR08 +U3FLz0RIJKtUKZ9nnLKBBJw1Rk05tapHQAZTf5VMaxRJ+4LHZF4eD708JBOo +sV4lgh8Uk18BtTsigQBGW645XUwKkcHn/vhK6iIuB5hWTGM2znBYnsrVZGkS +YD4GH9OMmxHkvUpEP1jEaIjTSn8wklYkAQoVJ6Qsu5eURpIn2L2c4580E3Pc +ZJpP0LTUNpGODz1riH9dNWuIdKVsSEoC2gnKCXH2YhpAFNOAiLIOBwo8ZLY3 +boLRkK5dOU2lbjDJTnmYNdjBq8MGFVIN9ppU7ujVoVKTVIoQ4UiEpIaYS+IA +aTyzOYviyFUqJKO6fOT8hSaXr2AMoBmE3fhjAEkOLCoTYUHpB9fJHjAYnC/m +e5D24jwg0PBjoKUIBVk6SJGHlnwyjisEYvaMqops5vMyH8DEBHMwVmT6cVSj +0oYEjY0g2ZYpp1JWSZtDsK8VZJl/Kt2ukYbiVB6xtsSzPus+fvwQ/F6fPels +tp2qyRypDa/Ca8OSrxVq54a3xdk3DGkch2F8kSqP+eb4FaxsalipC470HvvS +gWr/a5uR0bFwjQIBap4NKA0tqqOg4GaGCkW2NlX3MPahXuJofbH0rmTBFbdP +xnzVkK678HWgdnkSkaEiVeTcUasgyUcThs8RyHICCVt0WxI/MAwDqbEHDVaz +j+XGMdBSXY28YkR/tBXdw4x+gh19mb5XhDkwVB60A57rNAPwUAzxBUyckeLo +t0GKYTiEemOklYzLbgW6eRnIg9/RVjKiV2mDhuiztuXHDD4EIZH7jA0k7ZfK +DurOFIpoVZ4pHE5DFqn2wHGKXfcJyKaideBg/VS2UWDZR33W0YYChX7kvggD +kMQJVJIctF5nE7s+eJPOU4JaDnF8suXu7exDRExS7o796RWNQ/aZz+dxkiG7 +jQiKS6opmE412DwfgVDIAGBy1QB0mqkSRRqT8AzXxfegN5RdgDqlKAmpn1Rj +5SlYEKqXAtP1GhNVHYFlaZVxHoYuWAf2RijUIiKgIP4I/JLLNgcqp4A59Zyi +kL62c5nxSefiAkVXVzfdJcmzz9YkS7bY3uk8fffLmkUG3NdyltLVJDhOqQGV +J0KJHx5r2PKtsHCf/YK6Ap12RiQNckalEYCU0fVgc4d2rAyPUhnMszFt5xOO +aQwoPZhS4AUx8F0JB/BbowUD/gVjsjuVHws2SQR1KkFusxkmyVBogy3xDHIa +e+L5DjJfrokSHGpiiemdZkWPXEq6hD06TyvqRPmtqU4AQOwZoSIjOag4yjGa +tYtZcPwYldOZ6zKVQyqXqdySNPabVO6F5gLMLRSuMgrkUwQHmVBVAdSs3aVF +JARDi8gVaKRVsdGodAJ3im6ZJ/jziVMXtEQRSAYzdGUGd8tQO1IlQu1Nl0iQ +iqM+W+ZGraR8sMwurORMAESCfS7tGGS7q/AuFu4GQADwoazDas9LuWIsuCFW +HLRxHiwK62uRpsGkKlJCrf+CMwG/gn1MzDt4mTxV4rPCByZBcpSfpByp7BJ3 +C1LBFZL0q5IECpj6K6McSoYoBD+mFlSyBJAlZWVVUoiuL+cjwxX5vuKo3o3J +0rfRaKmxqHEbMN7DXPQ2aE65mT+p2eSRNpiS0ttK9yqP79b4IPoIMPC/SFLq +UiXLVR659pBJ+JU6/1cdzKrykcPSFklGX+rNlmjeWPOcwgFM+sFyyJJcNLAK +QFqwQYF1QnAvqXxnLwaUannc5adsiaePuzNKv+2QQ5binuDZZJJgrx3zGdl7 +kY314nSYktsdwJIt5jqr3ZphnmxZ8i+wIhHlqY3Zx8HubJxS1152L915DL5L +VlipVZXKkEaHOAmTIKzLIjGhQ8HC4c15khWHWsBV5uVJIiJv0bDo0GeMERly +6aEqPIGSPFJnPiBdNs0jPwEKZ0EYAhiYst0R7hNnBU7KrvTHgrJ1t9NRx3fe +lOOK2MEM8Fi7yORKLJCOvZuKSKCW6i4XPten6g25MKR3yaLkYnniF7EhJz6j +Vln6jEkONWWpqjLe9a4e1mzAJ/qoD4+J1GNNmjNUvfDTAIwt47M5CHhrlMZh +ju3aYvCGgIERxmEXu5gKAMBztGqr2ZIHfx7UwsKjsTTAc6Zh5+mvbbfdgX+s +3e6122x79+R0yGyEfzs4+BsT89ibOk1Ks6nmhWpTVuzD9uVe7TUsaUvZGnF6 +rWk9+8V1rVYLyPDjHghKeOdUwwtBB7AgWSLWy6xjEUot+5odg6UXqmZu9ato +h5RIUe+6z9UxhVFRboWh9oppJSkoLQ7IBwuhNhBnU8Hx+FIdaSvFDAAIKm7k +gMXVmUIqU5Wi7QCJawKGC5oF+07EBIxUoNlAmH+5NdhSKmy9fzl4G0FgLGhk +b+S89INdXMngETcvWci3buE1UzVyVo40p9kshNBE6yaLptyamwjpTRVtqdor +1Eyddrutqh4kxT1MJ3oHVLktjzMKwogpeqS6aVgAN70sNkmGgUOzxaUXNhXD +nYpslkcTqOzmoQAr05hssIxVGKqBBRs/y0K99PjKEeDlANy54RsKmX6maElI +C/uA+BBinTXHqysplCpkMA12HsECELTzWYOu71yimtgBZkJj8sTinzm21IBQ +DO3RJIT0Ea+i/EU3zBJBBzywoYtpHOK9iDRzKKq8Ay31E37BQ1lPX2AymxUH +02BxEXvO2uhVoIZm9hD//t9//9fQIfNN8Ng6zRBsWAoR4ShhQoWSwBRt0bWA +kCBRnghw7FmWBKOcQo+0TXUwJpfiHvgGSv/wfB7Qe1PgnFGI0xGDPaTPtIg0 +9yzOCmNHEi+KHbKxABnrtirYkUkPHWGauB1rlkP5jxqgMnyolSSnFZ3Sk4MJ +xEkZUhT/0Z0kH1UjAquskoxmReSgupJGWcuyBHD6wJg5zdp+cSIVy+wuKhnd ++dJbs0iBmGZUExKUVVPqkJCs1lqboLn3fH22Hrm3vR7dMvMzs991nIKLmD4q +lcSQvJqEb1nz6/dZHzAWZPaIR+eQuPIoHaNTMZ49X7Kmneaj/4SA2NN7R2np +pKGn2uLfl9rlcLfz0X10TzSftTdjdmVDOmn6udQsoe8OhVmtNlJJuw65K1M7 +6RaNLl2XEfIta379PusD1dVYSzsoVn2wTEnhVZXmta3CQnN6Rs7DadxN77UM +ETiTKtK284N2uhzuThncX8Xt3Y5SgyBNc47pNY/KjO6nU7SExhszn5nCt6+L +cO3U5P8tglixodVOuJiJprWueJpHt1rTd1uTkjFZVNgYe6Hub1BkxqQO0kNI +fvEETxZ1MirfFqRsGaYBUgP02a6/c7LlvhILgLMdq+4atVssjzdUqPepa5Tq +zMh0MLIvlkKiQZdF5dExZVtc5yIzjlm07qBhnmPkRMU1IKje44mAFCZRpUvZ +4qSkE7MryHzp9i5yIVxgZcXPaVmAxVx6VlTNvoByJ1S1JpWgFSICvG+K1TjW +WlBZ0GENjxYsJgKwxaBK/1kwmVIWptI/mZQXq+Exp75+Ei6aWix3ueVSOJKu +M0VXX50/4wXPUj4VGAsRw3vhg7/TB6AqvQ/A71WAG2xN3t8vOe7ifNcvruGs +NehWgTJAmiURm+u8X+/2PljayWJaVgforXcNAMjwtLa9FNmbfGSbcx2r5q6N +G2RqJ22jaOngezN71NQqLEZ7U56YaFwGOXgCXN1ho4YSy7o+K2rHd1uvX++e +nh3vnuwe/3X37N3B6f7O8da7BrkjG4shu5hfdGAqo5Dtn2m2y2PHz8UuizfX +doUKY9ftS9p3dacaj75Z3L5sV6bc+OQ4qsUuhUFHD0XoBFHI2lgaPKnu7aHE +1jk9aK4mHJDv4Fv3dRyf5/MbodiSfZdK+o95vjQJLA8N5YQaNIBqRs2RRKvO +cSXi6zayxq593Ku/b2NPIMtTFp9jxYT4Zb/HkpVZn6R0XZeewx7VH1QEWFuo +OeIhced5X1Z8Vv2Bqx+YlaihqiSKinQb1cKntP+SP4ag3m3cjE+lW9FCkMKv +n5GYJN1pGHLftTb+chMzVq1jKWJNsdnaskVrmr2RX/L5+sJzJhLU0kwVnvrj +6sKzDodlpxyT/X1tfrfNLhoL+CWlLP7D8scvSBsPwdbltxvM4vYnrb+EopVJ +IrP/7djFK7ysxQZ72/D/2+MDI1O8jWabdtj8FPiNLD4X0W9X3yvPX8mBO2eq +9kIUo6O4V2Ph29esD9wx4ZaZWigt4mza+iQ5HPhXLS/kwUzJZUXlJl827V36 +cimWP0319SUGRHleJG8Xf0cb+kFmRJak6ZXhs1Jt/QhjuEs3izaG+mon3uCE +9Pse9vAta9YH7rnNLzMG2FHB3luNAV/2tS/onNRhdcA/xhi+xAygVFbUq0O2 +n7LyElpubTNI/V/SY/hxqn+rHhZtBq36dA1QX/O9jYBvWdNsMxjdBWZ0FyCF +icPAW8jzC9UCwEsEeANPtx6WJg+2zqEA6gIS+TN1a05VtZ3ukzITlJP7zIbI +jFd9PKEvscuAgM0PhcEsUJYGzjLxlY9WtjpU2MEE78aXkkTlkhTeRiBoeZOD +jsux6YAFBZ2q8Ggh2Vg7zG9a+/EFNhfoergX56FfXAlVoOOczhqzmK6SC/xS +MdA3DebqtF+yhpr28hC/YYmIY8I8QTyux+nsM/emeAS4lkcUd+HpGpY8utmf +qNaIwoYNDtXegMUQJ16+w6vs6raCVkOtFaAR6nqyOnDCKuNj4Od0OT2IUt3u +WBUGTW2YnqE0db+ikKzKlhtsTcO6+Kw8G1btieJaeXlAj192HedQQviC+8Aa +oRRGf7QKkvpmEig1jRRN5YMNI3eXZDbuv4quj/RiTbkSocZLN/SmIKWp1bNI +fwrN1CDAKYPwos4C2UV4i/5fT44GRQx3brQtDnePt/e3Bqdn20eD0+Ot7VPc +UgF+sxdQqXluNANWxWWjzrxZp5vl1s1CfTknrNOjnaMe8+N8FIJ6E6Q8j6RL +vzTwm3WdilB+yRPmbYMGnujPBUeanwpZkqAh2Zeo8Wg9hwLikCfnO0GSLRja +rmXfqL0bkkQ6GY7xkYMtA70QfEaWy1K+3izaPjoYnO3svjk6OTjVjSJDmtW2 +jdHJQQGr3k2xD2Uvn1mtnaKmFXCFopqDNZU155T7Yo9YpdWhIrgCXvYIbw2Y +tXSNetlrkqwxVMzs/JE+ULGvUEroAuYT6gx2D9Rur25Ig5SJMBgdBZ3RXlPj +ocikivsNUgX0/YaK5pSPZ3wBbnokMuwTf5KrXNEXEIGN6JgR+2/a5d1IeUxn +J0dkN1Bv07iQ1e+XoiItVRN2JLCe5ChlW2rfb7b+frgLf49efZuFr0o/vsrE +dQdHbaTSwdFzWvfp4tSuDuiPd3VwSriyg3Pf7s9DUjhyyXJABSYjVMEeuya3 +FWCpfw+1StABiO5j1VOw27duAN56sN8a8cybunpFMwFcerBfesgytlUiWaPm +Na6WEF7uvcGqSiB5s4pwprmpOWQmd7du+euZtQryoT5yqHStNWFNdEVl7/q+ +SKWRlDpU63Ar5EV7+95oa+FgVfr01WxTrzuyry/kQsVXVPiq/UWHFKbzxZhX +dKHrazjfypAKwrKbLVvZX0Yzih+vp6f4q1d4K/6+03V807qTCLyQhgd8ybmL +2O7vWVIgxc9DvNtsXAa693TtVs/KZAPztgv7/rwAHq5X41LFV5NSrN8fXf21 +qvCndRvLNvA9Cv8lkdGMVHJTpOnrTnWmUYQPEejWS50IYOYAu3/DFODlLub4 +ewfHh7emnDcTSjNnU8neEv4YM6tVlZxxR6qJqU/hUXXiw1ztII2csn4yWswi +/1DPOB2dY+CvveQJ/sDaNn6BwFclZ6p+A2yHfgPsATvAm8p1iEEc4a+FoHqM +uHdOPzMk72CG8QQ/bXnovUPhT+SPzX3qyV+sEn5/bczDVKxdVdahiwn0g1EX +9JMS9LVeWe3TlxXUVU/5u2xsT/j0o2CH9M3oBDsN1q6fe+U1gWORCg67ZvaL +wxd78hv9ZZMBr+fhnvDcTOAbEgQU4/8PrCtZZO1PAAA= --> </rfc> -