lsd0009

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

commit 018ea9e7e0bcadbbd849f3f90cbbd08cee1c48c2
parent 3ad0ff1ca646cdb9e1d5d9a0432a99bccf868f4e
Author: Mikolai Gütschow <mikolai.guetschow@tu-dresden.de>
Date:   Mon, 11 Aug 2025 19:27:42 +0200

notation: bigEndian -> uintx

Diffstat:
Mdraft-guetschow-taler-protocol.md | 85++++++++++++++++++++++++++++++++++++++++++++++++-------------------------------
Mdraft-guetschow-taler-protocol.xml | 336+++++++++++++++++++++++++++++++++++++++++++------------------------------------
2 files changed, 233 insertions(+), 188 deletions(-)

diff --git a/draft-guetschow-taler-protocol.md b/draft-guetschow-taler-protocol.md @@ -57,16 +57,12 @@ Use at your own risk! - `"abc"` denotes the literal string `abc` encoded as ASCII [RFC20] - `a | b` denotes the concatenation of a with b -- `padZero(12, a)` denotes the byte string a, zero-padded to the length of 12 bytes -- `bits(x)` (`bytes(x)`) denotes the minimal number of bits (bytes) necessary to represent the multiple precision integer x -- `bigEndian(16, x)` denotes the 16 least significant bits of the integer x encoded in network byte order (big-endian) -- `bigEndianAmount(amount)` is formed from a fixed-point representation of `amount` - as `bigEndian(64, amount.value) | bigEndian(32, amount.fraction) | padZero(12, amount.currency)`, - where `amount.value` is the non-negative integer part of the base currency, - `amount.fraction` is given in unites of one hundred millionth (1e-8) of the base currency, - and `amount.currency` are the 3-11 ASCII characters used as currency code by the exchange. -- `random(256)` denotes a randomly generated sequence of 256 bits -- `a * b (mod N)` denotes the multiplication, `a ** b (mod N)` the exponentiation of a and b, modulo N +- `padZero(y, a)` denotes the byte string a, zero-padded to the length of y bytes +- `bits(x)`/`bytes(x)` denotes the minimal number of bits/bytes necessary to represent the multiple precision integer x +- `uint(y, x)` denotes the `y` least significant bits of the integer `x` encoded in network byte order (big endian) +- `uint16(x)`/`uint32(x)`/`uint64(x)`/`uint256(x)`/`uint512(x)` is equivalent to `uint(16, x)`/`uint(32, x)`/`uint(64, x)`/`uint(256, x)`/`uint(512, x)`, respectively +- `random(y)` denotes a randomly generated sequence of y bits +- `a * b (mod N)` / `a ** b (mod N)` denotes the multiplication / exponentiation of multiple precision integers a and b, modulo N # Cryptographic Primitives @@ -198,8 +194,8 @@ The final output `OKM` is determined deterministically based on a counter initia ~~~ counter = 0 do until OKM < N: - x = HKDF(salt, IKM, info | bigEndian(16, counter), bytes(N)) - OKM = bigEndian(bits(N), x) + x = HKDF(salt, IKM, info | uint16(counter), bytes(N)) + OKM = uint(bits(N), x) counter += 1 ~~~ @@ -228,7 +224,7 @@ Output: ~~~ info = "RSA-FDA FTpsW!" -salt = bigEndian(16, bytes(pubkey.N)) | bigEndian(16, bytes(pubkey.e)) +salt = uint16(bytes(pubkey.N)) | uint16(bytes(pubkey.e)) | pubkey.N | pubkey.e fdh = HKDF-Mod(pubkey.N, salt, msg, info) ~~~ @@ -345,6 +341,29 @@ out = (data == exp) # The Taler Crypto Protocol +## Datatypes + +### Amount + +Amounts are represented in Taler as positive fixed-point values +consisting of `value` as the non-negative integer part of the base currency, +the `fraction` given in units of one hundred millionth (1e-8) of the base currency, +and `currency` as the 3-11 ASCII characters identifying the currency. + +Whenever used in the protocol, the binary representation of an `amount` is +`uint64(amount.value) | uint32(amount.fraction) | padZero(12, amount.currency)`. + +### Timestamps + +Absolute timestamps are represented as `uint64(x)` where `x` corresponds to +the microseconds since `1970-01-01 00:00 CEST` (the UNIX epoch). +The special value `0xFFFFFFFFFFFFFFFF` 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". +--> + // todo: explain persist, check ## Withdrawal @@ -371,7 +390,7 @@ persist (reserve, value) | master_secret = random(256) | persist master_secret | *(coin, blind_secret) = GenerateCoin(master_secret, ?*) | -*coin.h_denom = SHA-512(bigEndian(32, 0) | bigEndian(32, 1) | denom.pub) +*coin.h_denom = SHA-512(uint32(0) | uint32(1) | denom.pub) *blind_coin = RSA-FDH-Blind(SHA-512(coin.pub), blind_secret, denom.pub) sig0 = EdDSA-Sign(reserve.priv, msg0) | | | @@ -398,11 +417,11 @@ persist *(coin, blind_secret) where `msg0` is formed as follows: ~~~ -msg0 = bigEndian(32, 160) | bigEndian(32, 1200) /* TALER_SIGNATURE_WALLET_RESERVE_WITHDRAW */ - | bigEndianAmount(sum(*denom.value)) | bigEndianAmount(sum(*denom.fee_withdraw)) - | SHA-512( *(SHA-512(denom.pub) | bigEndian(32, 0x1) | blind_coin) ) - | bigEndian(256, 0x0) - | bigEndian(32, 0x0) | bigEndian(32, 0x0) +msg0 = uint32(160) | uint32(1200) /* TALER_SIGNATURE_WALLET_RESERVE_WITHDRAW */ + | sum(*denom.value) | sum(*denom.fee_withdraw) + | SHA-512( *(SHA-512(denom.pub) | uint32(0x1) | blind_coin) ) + | uint256(0x0) + | uint32(0x0) | uint32(0x0) ~~~ The wallet derives coins and blinding secrets using `GenerateCoin` from a master secret and an integer index. @@ -426,7 +445,7 @@ Output: `coin` and `blind_secret` are calculated as follows: ~~~ -tmp = HKDF(bigEndian(32, idx), master_secret, "taler-withdrawal-coin-derivation", 64) +tmp = HKDF(uint32(idx), master_secret, "taler-withdrawal-coin-derivation", 64) (coin.priv, bks) = (tmp[:32], tmp[32:]) coin.pub = EdDSA-GetPub(coin.priv) ~~~ @@ -489,15 +508,15 @@ where `msg0`, `*msg1`, and `msg2` are formed as follows: ~~~ h_contract = SHA-512(canonicalJSON(contract)) -msg0 = bigEndian(32, 72) | bigEndian(32, 1101) /* TALER_SIGNATURE_MERCHANT_CONTRACT */ +msg0 = uint32(72) | uint32(1101) /* TALER_SIGNATURE_MERCHANT_CONTRACT */ | h_contract -*msg1 = bigEndian(32, 456) | bigEndian(32, 1201) /* TALER_SIGNATURE_WALLET_COIN_DEPOSIT */ - | h_contract | bigEndian(256, 0x0) - | bigEndian(512, 0x0) | contract.h_wire | *coin.h_denom - | bigEndianTime(contract.timestamp) | bigEndianTime(contract.refund_deadline) - | bigEndianAmount(*fraction + *denom.fee_deposit) - | bigEndianAmount(*denom.fee_deposit) | merchant.pub | bigEndian(512, 0x0) -msg2 = bigEndian(32, 72) | bigEndian(32, 1104) /* TALER_SIGNATURE_MERCHANT_PAYMENT_OK */ +*msg1 = uint32(456) | uint32(1201) /* TALER_SIGNATURE_WALLET_COIN_DEPOSIT */ + | h_contract | uint256(0x0) + | uint512(0x0) | contract.h_wire | *coin.h_denom + | contract.timestamp | contract.refund_deadline + | *fraction + *denom.fee_deposit + | *denom.fee_deposit | merchant.pub | uint512(0x0) +msg2 = uint32(72) | uint32(1104) /* TALER_SIGNATURE_MERCHANT_PAYMENT_OK */ | h_contract ~~~ @@ -543,11 +562,11 @@ check EdDSA-Verify(exchange.pub, msg3, sig3) | where `msg3` is formed as follows: ~~~ -msg3 = bigEndian(32, 344) | bigEndian(32, 1033) /* TALER_SIGNATURE_EXCHANGE_CONFIRM_DEPOSIT */ - | h_contract | contract.h_wire | bigEndian(512, 0x0) - | bigEndianTime(exchange_timestamp) | bigEndianTime(contract.wire_deadline) - | bigEndianTime(contract.refund_deadline) - | bigEndianAmount(sum(*deposit.fraction - *denom.fee_deposit)) +msg3 = uint32(344) | uint32(1033) /* TALER_SIGNATURE_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 ~~~ diff --git a/draft-guetschow-taler-protocol.xml b/draft-guetschow-taler-protocol.xml @@ -29,7 +29,7 @@ </address> </author> - <date year="2025" month="June" day="30"/> + <date year="2025" month="August" day="11"/> <workgroup>independent</workgroup> @@ -68,16 +68,12 @@ Use at your own risk!</t> <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">padZero(12, a)</spanx> denotes the byte string a, zero-padded to the length of 12 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">bigEndian(16, x)</spanx> denotes the 16 least significant bits of the integer x encoded in network byte order (big-endian)</t> - <t><spanx style="verb">bigEndianAmount(amount)</spanx> is formed from a fixed-point representation of <spanx style="verb">amount</spanx> -as <spanx style="verb">bigEndian(64, amount.value) | bigEndian(32, amount.fraction) | padZero(12, amount.currency)</spanx>, -where <spanx style="verb">amount.value</spanx> is the non-negative integer part of the base currency, -<spanx style="verb">amount.fraction</spanx> is given in unites of one hundred millionth (1e-8) of the base currency, -and <spanx style="verb">amount.currency</spanx> are the 3-11 ASCII characters used as currency code by the exchange.</t> - <t><spanx style="verb">random(256)</spanx> denotes a randomly generated sequence of 256 bits</t> - <t><spanx style="verb">a * b (mod N)</spanx> denotes the multiplication, <spanx style="verb">a ** b (mod N)</spanx> the exponentiation of a and b, modulo N</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> @@ -118,7 +114,7 @@ Output: <section anchor="sha512-trunc"><name>SHA-512-256 (truncated SHA-512)</name> <figure><artwork><![CDATA[ -SHA-512(msg) -> hash +SHA-512-256(msg) -> hash Input: msg input message of length L < 2^125 octets @@ -216,8 +212,8 @@ Output: <figure><artwork><![CDATA[ counter = 0 do until OKM < N: - x = HKDF(salt, IKM, info | bigEndian(16, counter), bytes(N)) - OKM = bigEndian(bits(N), x) + x = HKDF(salt, IKM, info | uint16(counter), bytes(N)) + OKM = uint(bits(N), x) counter += 1 ]]></artwork></figure> @@ -250,7 +246,7 @@ Output: <figure><artwork><![CDATA[ info = "RSA-FDA FTpsW!" -salt = bigEndian(16, bytes(pubkey.N)) | bigEndian(16, bytes(pubkey.e)) +salt = uint16(bytes(pubkey.N)) | uint16(bytes(pubkey.e)) | pubkey.N | pubkey.e fdh = HKDF-Mod(pubkey.N, salt, msg, info) ]]></artwork></figure> @@ -376,8 +372,34 @@ out = (data == exp) </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". +<!-- +// 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> + <t>// todo: explain persist, check</t> +</section> +</section> <section anchor="withdrawal"><name>Withdrawal</name> <t>The wallet creates <spanx style="verb">n &gt; 0</spanx> coins and requests <spanx style="verb">n</spanx> signatures from the exchange, @@ -402,7 +424,7 @@ persist (reserve, value) | master_secret = random(256) | persist master_secret | *(coin, blind_secret) = GenerateCoin(master_secret, ?*) | -*coin.h_denom = SHA-512(bigEndian(32, 0) | bigEndian(32, 1) | denom.pub) +*coin.h_denom = SHA-512(uint32(0) | uint32(1) | denom.pub) *blind_coin = RSA-FDH-Blind(SHA-512(coin.pub), blind_secret, denom.pub) sig0 = EdDSA-Sign(reserve.priv, msg0) | | | @@ -429,11 +451,11 @@ persist *(coin, blind_secret) <t>where <spanx style="verb">msg0</spanx> is formed as follows:</t> <figure><artwork><![CDATA[ -msg0 = bigEndian(32, 160) | bigEndian(32, 1200) /* TALER_SIGNATURE_WALLET_RESERVE_WITHDRAW */ - | bigEndianAmount(sum(*denom.value)) | bigEndianAmount(sum(*denom.fee_withdraw)) - | SHA-512( *(SHA-512(denom.pub) | bigEndian(32, 0x1) | blind_coin) ) - | bigEndian(256, 0x0) - | bigEndian(32, 0x0) | bigEndian(32, 0x0) +msg0 = uint32(160) | uint32(1200) /* TALER_SIGNATURE_WALLET_RESERVE_WITHDRAW */ + | sum(*denom.value) | sum(*denom.fee_withdraw) + | SHA-512( *(SHA-512(denom.pub) | uint32(0x1) | blind_coin) ) + | uint256(0x0) + | uint32(0x0) | uint32(0x0) ]]></artwork></figure> <t>The wallet derives coins and blinding secrets using <spanx style="verb">GenerateCoin</spanx> from a master secret and an integer index. @@ -457,7 +479,7 @@ Output: <t><spanx style="verb">coin</spanx> and <spanx style="verb">blind_secret</spanx> are calculated as follows:</t> <figure><artwork><![CDATA[ -tmp = HKDF(bigEndian(32, idx), master_secret, "taler-withdrawal-coin-derivation", 64) +tmp = HKDF(uint32(idx), master_secret, "taler-withdrawal-coin-derivation", 64) (coin.priv, bks) = (tmp[:32], tmp[32:]) coin.pub = EdDSA-GetPub(coin.priv) ]]></artwork></figure> @@ -521,15 +543,15 @@ check EdDSA-Verify(merchant.pub, msg2, sig2) | <figure><artwork><![CDATA[ h_contract = SHA-512(canonicalJSON(contract)) -msg0 = bigEndian(32, 72) | bigEndian(32, 1101) /* TALER_SIGNATURE_MERCHANT_CONTRACT */ +msg0 = uint32(72) | uint32(1101) /* TALER_SIGNATURE_MERCHANT_CONTRACT */ | h_contract -*msg1 = bigEndian(32, 456) | bigEndian(32, 1201) /* TALER_SIGNATURE_WALLET_COIN_DEPOSIT */ - | h_contract | bigEndian(256, 0x0) - | bigEndian(512, 0x0) | contract.h_wire | *coin.h_denom - | bigEndianTime(contract.timestamp) | bigEndianTime(contract.refund_deadline) - | bigEndianAmount(*fraction + *denom.fee_deposit) - | bigEndianAmount(*denom.fee_deposit) | merchant.pub | bigEndian(512, 0x0) -msg2 = bigEndian(32, 72) | bigEndian(32, 1104) /* TALER_SIGNATURE_MERCHANT_PAYMENT_OK */ +*msg1 = uint32(456) | uint32(1201) /* TALER_SIGNATURE_WALLET_COIN_DEPOSIT */ + | h_contract | uint256(0x0) + | uint512(0x0) | contract.h_wire | *coin.h_denom + | contract.timestamp | contract.refund_deadline + | *fraction + *denom.fee_deposit + | *denom.fee_deposit | merchant.pub | uint512(0x0) +msg2 = uint32(72) | uint32(1104) /* TALER_SIGNATURE_MERCHANT_PAYMENT_OK */ | h_contract ]]></artwork></figure> @@ -576,11 +598,11 @@ check EdDSA-Verify(exchange.pub, msg3, sig3) | <t>where <spanx style="verb">msg3</spanx> is formed as follows:</t> <figure><artwork><![CDATA[ -msg3 = bigEndian(32, 344) | bigEndian(32, 1033) /* TALER_SIGNATURE_EXCHANGE_CONFIRM_DEPOSIT */ - | h_contract | contract.h_wire | bigEndian(512, 0x0) - | bigEndianTime(exchange_timestamp) | bigEndianTime(contract.wire_deadline) - | bigEndianTime(contract.refund_deadline) - | bigEndianAmount(sum(*deposit.fraction - *denom.fee_deposit)) +msg3 = uint32(344) | uint32(1033) /* TALER_SIGNATURE_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> @@ -692,7 +714,7 @@ msg3 = bigEndian(32, 344) | bigEndian(32, 1033) /* TALER_SIGNATURE_EXCHANGE_CONF -<?line 562?> +<?line 581?> <section anchor="change-log"><name>Change log</name> @@ -710,125 +732,129 @@ Education and Research (BMBF) within the project Concrete Contracts.</t> </back> <!-- ##markdown-source: -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 -fiHJQNb3f2muy5AjSQAA +H4sIAAAAAAAAA808a1vbPLLf/Sv00i8OG+dKaZtt2qVcCqcl9AG63T1dlii2 +knhx7BxfgLwt7y87384f25mRZFvBXEt7Ng8PsWVpNJr7jOQ4jmOd91jXslI/ +DUSPrRxPBXs/+MyOeSBi9imO0siNghXLi9yQz6CHF/Nx6kwykSbuNLpwUuzo +zFVHy+WpmETxosf8cBxZlj+PeyyNsyTttFqvWh3rIorPJnGUzbGHJ+YC/oWp +laSx4DOz7UwsoLfXsxhzGM1DV268mKfRJObz6YIahMuTKV3N+WIGIxPLenYu +wkz0rGeMxWIe9dg0TedJr9mc+GljEmahSBtRPGkGidcCxBrQ3MTOAeCfpEV3 +eF7RvWlZPEunUQy4OTAzY5I4+/5ZFHCfvf+//5XkoWcwsMeOP2+xrVgksDL2 +OfTPRZz46YJFY3Ys3GkYBdFkQb35aBSLcxyg+1MzEkgAYrsimE2jIP0dGhqs +3aKHLoDqGd3dyAN8tpxWu7X+SrVkYYqMeS/iGQ/lZGLG/aDHZhLvRs7Wv6SZ +40lwDU9YVhjBmBSwRmYc7mx2Wvqi3VpTl89frr9Sl+udLrXuftjaASwO9hrt +Fvy1XjRfvXjpdJ31tY7TXoNezovT7hp0PNo9yvuttzovm4O9o+PGzt6no0b7 +ZctZA0ECccpxsCzHcYBSQAPuppb1j6/s+N0X9o8T+WDme14AWD9je7DkyMvc +1I9Co9s7ccFjwdIpT+GfnzAQ8Axlh8F1kvpBwFBSHT9E2Z4AKRLGQ4/N+AIo +GabcD5mI4yhOGtbnRDAAs4iymEUXIYv95Ow3nH0QpVzO7LDhCh+5K0MGFI1A +xGBSwQI/FTEPkLd+OGFD6DFkIkTeeYwnbONoc2+PfSV6nyAMzr6zkQkDkEGd +C2kiFCfOLvx0ykbYf869/xZxZC/qjNfMcaNFKvTEvM5+h24OdMeZ00hiJ8IJ +AAKQC+qdIMSRnyb2ZW3YHFITXhpgZ37oz2BJYTYbgQGBwTiiSZ1ZKFygI48X +OAWoJVAVKU7jsiD154Fg0Oj6Ca7FD8GUAIxLnDeDO1zG8nzDxRAQ5UnKEn8S ++mPf5QAR58S5sYcGM7wsaAvMA41GBks6gJWBHvbIn0AXz+dhTc/ZXperxetu +p7heXyuuO89LnZ63qReKkfifzD8Hs4VLjNQS2uu0BtnX7nbKd+tr5TuAWr4F +uHRbB8Ilc+GiIgQLRDMGuYxm9qJEGc5kY7BgExGCjKWw6ATwAQIIxVEgkRSp +VTZi9izy2AAgNKnFaDLYK9kEVCZxazJxOY9CWKGfy9/NnES8UIdGdQawsyBi +A9SSzcKe+y64HH/m4+LQiC8/3AVDz3aykPSZOjwD07HhAK3Yt2fJlMPFlWX9 +8ccflmq2Z8mkxpw3bIo+wtoL51naI9MHD/ALkIMmNkPBnBBtlNx/ZK9Z55/r +bRa5qUCXcpCl+WCERkDUMM+fgNvA0WP/EmitYCC+H8Hg91m3o+EgctYQAZCQ +IFUjgoyj9WJA+ecgkUdCrpStNdp19hz/reM/pOJ6o4Mjvipze9IoyAGyIskB +FyVyoGj+IDnanedPQ4/1tXvTA1dznR4dpEcH6dHV9Fi7hR5EVRsCEbKWnm6u +5XRy6JlJracQoCej2JIEHRd0UsRzoxhNQxR6iTbhYz8GmPlIbRKv09cTYz+U +hvHbNyU4Vz1JjFTM5jB/WYIswr7P8NHXVq/bPpFIgcMr+9RojqYHLYDnj8do +AMZxNNOQmkrQS3N/hTjgBC+k4QY7AK6E5gI7mglgKdqEfUWyDQjB0PQoY7QJ +pl3ZhN39jU3g7HTGNUexxUFi2hBV1gHxy5S4CqQAvswRgOTLruKLaxgewmGs +DI90sIqIJp8MAYGZSEAS4cYipdtCOniq/JYeiT0RrUKkPJ5y8ugxGGv0mnKo +KUeABlPfiqdLGEn9gsekXi4P3CwgFVgivQrmThSRPwC2WyIGB0ZLXjK6GNgh +gc+88ZWURZwOIN0wjNk4osayRM4m0wsfYyq4TVJe9iBfVTB5YhGhwU8r+UFP +anACBCqKSVi2LykUJEuwfTnHryQVc1xkkk1QtdQyEY+TnjXEb0eNGiJeCRuS +kIB0gnCCn72Y+uDFdEcEudwPBHjIbHfcAKUhWbuqNZS4wSA74UFaZ3sf9uuU +DNXZRxK5gw/7SkwSyULsRywkMcR4EBtI4pnNWRiFjhIh6dXlo9qfaXDx8cfQ +NQW3G537EOTApDKYFRR+cB3sAYHB+GK8B6ErjgMES3YMpBR7QaQNXOSBJZ+M +IwNBjIBRVJHMfF7EAxiYYAzG8mg9CpewtCFAYyMImGXIqYRV4lajvh9VzyL+ +VLK9hBqyU1nEpSle91nn+fNVsHt99rK93qqZKnOgFnwTXBum/KhA165ZWxx9 +TZHGURBEF4mymJ8OP8DMZQkrZKEmrceuNKDa/tplz1izcI4cAEqeDSBLUrQM +gpxb2VUotLWqOvuRBzkPR+2LpHUlDTbMPinzVV2a7tzWgdhlcUiKiliRcUep +giAfVRjuQ+DlBAK28LYgflBSDMTGHtTZkn5UK8dAc/Vm4IYS/X9r0T3U6Bfo +0cPk3WDmoCTyIB3wXIcZAId8iCdg4IwER1/6CbrhAPKNkRYyLisOaOalI/d/ +R11JCV8lDbpHn7UsL2Jw4weE7ms2kLhfKj1YNqaQCKv0TMGo1WWSag9qtXzV +fepkU9I6qGH+VJRCYNo/9VlbKwok66HzLvCBE0eQSXKQeh1NbHtgTdqvqFd1 +j8OjDWdnaxc8YpxwZ+xNr6gdos9sPo/iFMld8qA4pRqC4VSdzbMRMIUUAAab +CqDDTBUoUpvsz3BevAa5oegCxClBTkj5pBwrS0CDULxUN52vMWHKCExLs4yz +IHBAO7C+Qa4WAQEG0TnQS07bGKiYAsYsxxQ597Wey4hPGhcHMLq6um4uiZ99 +tiJJssF2jufJl99WLFLgvuaz5K5GoVYrJMB4IhT74bHuW1wKC9fZz7HLwWlj +RNwgY1QoAXAZTQ8WaGjFSvEolME4G8N2PuEYxoDQgyr5rh8B3RVzAL41WjCg +nz8mvVPxsWCTWFC1Efg2m2GQDIk26BJPIaaxJ65XQ+LLOZGDQ40sEb3dMOTI +oaBL2KOzxBAnim/L4gQdiDwjFGREBwVHGcZy7lJOOH6OyOnItUrkEMsqkasI +Y39I5N5pKsDYXOCMVkCfPDjwhLIKwGblLikiJpSkiEyBBmqyjVqlEbiTdVWW +4D+PnTqhJYyAMxihKzW4m4fakCoWamtawUFKjvqsyoxacfGgSi+s+FRAjxjr +XNowyHJXbl0sXA10gY6rMg9bel7wFX3BNbZio43jYFKYX7M08ScmSwm0/gZj +AnYF65gYd/AieDL8s4IHKkF8lHeSj5R2ibsZqfrlnPRMTgIGTH1LL4ecIQzB +jqkJFS+hS0VaaXIKwfXleCS4Qt9TFNWrKZP0cziqVBbVbgPEe6iLXgaNKRbz +H6o2WagVpsD0ttTdpPHdEu+H59AH/os4oSpVXC3ySLVVJvvfKPN/1c7M5I9s +lrpIPHqoNauQvLGmObkDGPST+ZDGmahjFoC4YIEC8wT/Xlx5YisGmGp+3GWn +bAmnj6srpX6bAYcoxTnC/cU4xlo7xjOy9iIL6/kOLwW3WwAlXcx1VLsxwzjZ +suQ3kCIWxa5NuY6D1dkooaq9rF468whsl8ywEsvkypBahzgIgyDMy0IxoY29 +3ODNeZzqYiVSlblZHIvQXdQt2vQZo0eGWHqoEk/AJAvVng9wl02z0IsBw5kf +BNANVNluC+dl7QaYFF3p2xyzrtNuqy04d8pxRqxg+rg1nUdyBRQIx75MRShQ +SnWVC5/rnfG6nBjCu3hRULHYtQvZkBOdUaosvcckmxoyVVURb7ejmzUZ8Ine +6sNtIvVYo1Ybqlr4sQ/KlvLZHBi8MUqiIMNybd54jcFAiNJmF7uYCuiA+2hm +qdmSG38u5MLCpbbEx32mYfvVi5bTasMfa7V6rRbb3D46HjIb+38e7P2NiXnk +TmsNCrMp54VsU2bsw9blztJnWOCWsBWi9ErDev2b41jNJqDhRT1glHDPKIcX +gjZRgbOErJtahyKQUvaYFYOm56JWXuqjcIeQSGHvOG+sAnvQ3gCj4DkeDkgg +kKTlkGp+8dOpF/MLHsik5AIjAsgcZArBhiF7w1rIGD+UG9Ux7vYlKT4aFsZL +VeCRAeISpDqcCBD/NI39UUYKKlegtg8UNBcoSE4SdzEBmjuF1ZfSFUxqJR3S +KM2pgEhc5FizsQDbpetNEEeUUaC9nTK4mjXLIC/CaEiFPhBEwoIAjkJNijhL +IC4vdA3EbhJQwibic5WhYfhZoKHYtZiNooANV4c4EigSpnLn3BUx7eyT/ZkJ +Hiaq4EU1IGChIEOPRCAhysvPRBakVt1SMvN21dw5Rd9+qbfFhy32us/errLX +LByqRK5c3FHcvfOjCWidheBT2CrRsAHe4aYBZj+IE5aqSmBI7vn5bmky99m2 +twUO7INYTERo1+4eqeSb2QpEXdXi7h75eGyXG5ziw+wRD8/A8wO/xyKGcKX4 +vKmY006y0b/AovS0pCHFtdXt5Wt5Smxv6rlMSYmJxOAHpp/xBJzdqQqI+6pi +ikcSbudRwVoTwn3mXLVRgeoyJFcDazD3e3WAYROe2gbYOmhQDUfiwMb0lKS6 +tFOpnGWr5DjbeJ1rSc1albMhgFIELZNyDYagY28Tt3oZDhjYVq4IlPzlDAEl +o7pSq4p0P0miUaib2uox80GVRNPHlCGDqPX7YFuiJYX/5fX+Cl1Y1fzfwm/n +YxSdZXO7vIz7q4SMI0r2FA1nSD4NdwcKh+KAz/bBBT0QshQUlS8ZdNfJ00Nx +1db4w983wSuCs4dg+AzdJuIro6HHQWyMeMAxnHsDyUg2sxVRpJP/k6YRuPdT +TZX7o748hfP0UyiplEUIozxTFtfCId4fsjZ1hTA8oZC/NnS5tAhTmZ0fUSyp +4iZldIkln/AWo6eUZCn7rzCbeh5jtCZfpd2XOawKpdB4UgSOe2FV1Q/soDYK +0MavGxa/04Lb5io73vi4fXh6tPd+sHH8+XD79MvGx4/bx6eH20fbh3+F273j +3a3DjS9stan3D5ZFsWa2Vcjj99z3wLL0ZbHmAqvWJXmiQgRrLAehjxS2LltG +Gw1r1cy7YptCxYweVX+SUiaQ17gkbROIi2kzo+xYhzIv4Mpv61IY7UsWdUiK +YTGEBl7QMdnYd9NggekPP6ODpNB3Ng/ELE9tPQEBdaASQsoTjQl8PBSKKTMm +RDyQOyo8XLAI+so6gMrPZ/5kShmByj5ksTSfDfci9RmRAJPxPKny/MTNkkTu +me8EUezzsIe5ASu7aBQqI7h4K0XLiD60DvjeJdW0tOSeJbWl0qMKe9Q34CrZ +QlwhUssNYe+S+EutRFyzJkXtjOmCrVNUuubcj3UxA3sZRU21v317bbPbUYd6 +ZTnLJSGgQkhZEYeUId9WeUzpcBht0SqxROrU2VKktiLfEyg5TpzR8fKjQit1 +OvmgzAYFTUhXLG7BFF973c5JneFVt9M7AdujrEsedL0X6adsVAxXmmFjhgYW +qk78x2oZnwgHOE+yS6kmptef5IsDj8/EZiLGVCxVmZi+vTkXW+6HuZhsk/XG +Vc38G8fmCTy+9pBGvyDCuoBI51RtkqmUoN15+XCPKY9bA2d9j/ZHXKHPtqTR +mQjf1ouZfiSLWW7IfSqzCYPGN5hfznhVTvp+xKeGERq6h6bE5cyJIEibdM85 +H4/tckOeOxB9kuY3SSffu2q6Afdn7I4UAj+2WgAGs5K4vzoRmJ6i+GirlIuS +0pP6IzFY0brqIEQnL6kpw3VfoPnhmaIMiUf6xxnYXE9wD4yvUPKvb+8ft0eh +PAXZL0u4VDDSLyXsjyNBYW8kgeulFTwK4O2rfmgCpBffoEXi4WRa7IOJ19Aq +TN8Ptm0azL0HXi8dGE5B1Q5+UmqRo1uXeDxValGR5ZZdolyUnLNWNbKaGbfP +eXywdQDhXgRBknAkGDq7IQ+VUMPb6pE6BSn2U/oMA74jEcgXDuwcn2+5FpBa +gd+Q00J8G2SeYPs8PtvyIWplmLtYq7DCtsnd1VKEswpkaFfXhSDJoD01GCzR +a3xDwmEWpaoZVwXCREkJqFRdNXhbZxriTd7oFzkSMMK5mN3qSPBj34j0r3Ak +UohUykdoNMoikgsFicL9KxIS7JaEaOsFPsRgdO4yGJ2fZTAkWwmF5dafbjA6 +JMidJYNxrVJQZ0PSq6F8LwgbOzKPual+MD0tec68fsHB5uCh1v86OhjkulSD +fMEsN7zolKsN7Va7stqwv324ubsxOD7dPBgcH25sHpfqDMX0FiFewF7Dgnu5 +lFENXJUyNg/2Bqdb258OjvYK8Ab8yuqCasQ1q/pCLtgqkvpuVoPzYYXL1YFA +uXHJveejVrUOmaU9pQdFt2uPoNHIq0y8kS2dm9mydjtbPm38fX8bvg8+VDNG +JpOlHJKVckiILCNIzBdyz1PVYfBEBnqemvlalDCOaeF5CHJt8iwJbdhjRQWL +trR9ycOFlO2l4wQNaze6wMoJHVB3oyzw8kOpqus4oxM0aUSH2QW+mgymeOrP +1XkDmYXRrpfyIpYIOWb/E4TjuBxfdkkyd4oas5KFlALA0xUsK+vdsljVfRQ0 +rN6o2g1MhjDx+B8eplfnJdQr+nk6DmRUB6TVzi4WLc59L6Pj8T7uLNPRFCUd +5QRdC0PzPkn60lapvr0rQS/6FQn6fZP7YvtADZT5BytlJGjP6mU5kx0Lz52H +AVSf02WKZfN5+9JLHW/dBm2OeOpOHT3jXZtGpaCoSASMEL6+ZAKuKhAv1l5n +psWXtLkJcaapqSlULhrcuuTHE+umntU7T3nM8FO2oBTwh+8/Ldn2J86S888T +pcuKCkZgYNBVBwdtFQM/FPINuxfLc9R+lCAGwOW9kIfhjOzH05AJ/lAKHsK8 +73CdGWjZiQWe7MFabXzmILQHZK2AipcFeJSudHTi3sO1WT0tIgfM8S7sB4XB +XTMMNmw1CUX36cNgmrdetYCfFAaXPZVcFEl69/YwuHvXhlm3CJW6a2vlWKnV +7VbGStt/w1Dp/TaGsDt7h/vXQs2lSPN6FGmEa2pIBSFLQyvqYHdFmN+rEzbm +VESU17bt8mEynzYDTnWwFn+FIIvxx3s28WCrp95xT9Tvy2zR78s8Y3sbg41r +PQZRiG+xoxyNOB3tY5vyCFwQTfBuw0UzHwhvIn/I6FtPHhkTXn9lzINErFwZ +89BeHP2QyQW96kyvm8kYkA6xqZN28jd/2I7w6Adn9umNvRjjT2vby9Rbh+ha +DkUiOCyZ2e/23+3IN02L0BNPPeGacE9H4AXxAUK0fwOz9Ab0SUoAAA== -->