lsd0009

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

commit 1d77ece1388a859b39cde44ace057e9024723238
parent a1509e657d610aeb94ba4ce943561ca02a9b8e4e
Author: Mikolai Gütschow <mikolai.guetschow@tu-dresden.de>
Date:   Tue,  7 Apr 2026 16:43:58 +0200

protocol: rename blind_coin to planchet

Diffstat:
Mdraft-guetschow-taler-protocol.md | 30++++++++++++++----------------
Mdraft-guetschow-taler-protocol.xml | 191+++++++++++++++++++++++++++++++++++++++----------------------------------------
2 files changed, 109 insertions(+), 112 deletions(-)

diff --git a/draft-guetschow-taler-protocol.md b/draft-guetschow-taler-protocol.md @@ -465,9 +465,9 @@ for i in 0..n: coinᵢ.priv = coin_seedᵢ[:32] coinᵢ.pub = EdDSA-GetPub(coinᵢ.priv) h_denomᵢ = SHA-512(uint32(0) | uint32(1) | denomᵢ.pub) - blind_coinᵢ = RSA-FDH-Blind(SHA-512(coinᵢ.pub), blind_secretᵢ, denomᵢ.pub) - h_planchetᵢ = SHA-512( SHA-512( denomᵢ.pub ) | uint32(0x1) | blind_coinᵢ ) -planchets = (⟨h_denomᵢ⟩, ⟨blind_coinᵢ⟩) + planchetᵢ = RSA-FDH-Blind(SHA-512(coinᵢ.pub), blind_secretᵢ, denomᵢ.pub) + h_planchetᵢ = SHA-512( SHA-512( denomᵢ.pub ) | uint32(0x1) | planchetᵢ ) +planchets = (⟨h_denomᵢ⟩, ⟨planchetᵢ⟩) msg = Sign-Msg(WALLET_RESERVE_WITHDRAW, ( sum( ⟨denomᵢ.value⟩ ) | sum( ⟨denomᵢ.fee_withdraw⟩ ) | SHA-512( ⟨h_planchetᵢ⟩ ) | uint256(0x0) | uint32(0x0) | uint32(0x0) )) @@ -477,11 +477,11 @@ sig = EdDSA-Sign(reserve.priv, msg) ~~~ (E1) coin issuance and signing (exchange) -(⟨h_denomᵢ⟩, ⟨blind_coinᵢ⟩) = planchets +(⟨h_denomᵢ⟩, ⟨planchetᵢ⟩) = planchets for i in 0..n: denomᵢ = Denom-Lookup(h_denomᵢ) check denomᵢ known and not withdrawal-expired - h_planchetᵢ = SHA-512( SHA-512( denomᵢ.pub ) | uint32(0x1) | blind_coinᵢ ) + h_planchetᵢ = SHA-512( SHA-512( denomᵢ.pub ) | uint32(0x1) | planchetᵢ ) msg = Sign-Msg(WALLET_RESERVE_WITHDRAW, ( sum( ⟨denomᵢ.value⟩ ) | sum( ⟨denomᵢ.fee_withdraw⟩ ) | SHA-512( ⟨h_planchetᵢ⟩ ) | uint256(0x0) | uint32(0x0) | uint32(0x0) )) @@ -491,7 +491,7 @@ total = sum( ⟨denomᵢ.value⟩ ) + sum( ⟨denomᵢ.fee_withdraw⟩ ) check reserve.balance >= total persist reserve.balance -= total for i in 0..n: - blind_sigᵢ = RSA-FDH-Sign(blind_coinᵢ, denomᵢ.priv) + blind_sigᵢ = RSA-FDH-Sign(planchetᵢ, denomᵢ.priv) persist withdrawal // todo: what exactly? should be checked first for replay? ~~~ @@ -774,8 +774,6 @@ where (for RSA, without age-restriction) // todo: double-check incompatibility between h_denom and hash of denom used below -// todo: rename blind_coin to planchet, here and in withdrawal, too? - {::comment} // see TALER_EXCHANGE_get_melt_data ⟨batch_seedₖ⟩ // see TALER_refresh_expand_seed_to_kappa_batch_seeds @@ -802,15 +800,15 @@ for k in 0..kappa: blind_secretₖᵢ = HKDF("bks", planchet_seedₖᵢ, "", 32) coinₖᵢ.priv = HKDF("coin", planchet_seedₖᵢ, "", 32) coinₖᵢ.pub = EdDSA-GetPub(coinₖᵢ.priv) - blind_coinₖᵢ = RSA-FDH-Blind(SHA-512(coinₖᵢ.pub), blind_secretₖᵢ, denomᵢ.pub) - h_planchetₖᵢ = SHA-512( SHA-512( denomᵢ.pub ) | uint32(0x1) | blind_coinₖᵢ ) + planchetₖᵢ = RSA-FDH-Blind(SHA-512(coinₖᵢ.pub), blind_secretₖᵢ, denomᵢ.pub) + h_planchetₖᵢ = SHA-512( SHA-512( denomᵢ.pub ) | uint32(0x1) | planchetₖᵢ ) h_planchetsₖ = SHA-512( ⟨h_planchetₖᵢ⟩ ) value = coin.denom.fee_refresh + sum( ⟨denomᵢ.value⟩ ) + sum( ⟨denomᵢ.fee_withdraw⟩ ) commitment = SHA-512( refresh_seed | uint256(0x0) | coin.pub | value | SHA-512( ⟨h_planchetsₖ⟩ ) ) for i in 0..n: h_denomᵢ = SHA-512(uint32(0) | uint32(0x1) | denomᵢ.pub) -planchets = (⟨h_denomᵢ⟩, ⟨blind_coinₖᵢ⟩, ⟨transferₖᵢ.pub⟩)) +planchets = (⟨h_denomᵢ⟩, ⟨planchetₖᵢ⟩, ⟨transferₖᵢ.pub⟩)) msg = Sign-Msg(WALLET_COIN_MELT, ( commitment | coin.h_denom | uint256(0x0) | value | denom.fee_refresh )) @@ -832,7 +830,7 @@ denom = Denom-Lookup(coin.h_denom) check denom known and not refresh-expired check RSA-FDH-Verify(SHA-512(coin.pub), coin.sig, denom.pub) check coin.pub known and dirty -(⟨h_denomᵢ⟩, ⟨blind_coinₖᵢ⟩, ⟨transferₖᵢ.pub⟩)) = planchets +(⟨h_denomᵢ⟩, ⟨planchetₖᵢ⟩, ⟨transferₖᵢ.pub⟩)) = planchets for i in 0..n: denomᵢ = Denom-Lookup(h_denomᵢ) check denomᵢ known and not withdraw-expired @@ -842,7 +840,7 @@ check coin.value >= value persist coin.value -= value for k in 0..kappa: for i in 0..n: - h_planchetₖᵢ = SHA-512( SHA-512( denomᵢ.pub ) | uint32(0x1) | blind_coinₖᵢ ) + h_planchetₖᵢ = SHA-512( SHA-512( denomᵢ.pub ) | uint32(0x1) | planchetₖᵢ ) h_planchetsₖ = SHA-512( ⟨h_planchetₖᵢ⟩ ) commitment = SHA-512( refresh_seed | uint256(0x0) | coin.pub | value | SHA-512( ⟨h_planchetsₖ⟩ ) ) @@ -854,7 +852,7 @@ check EdDSA-Verify(coin.pub, msg, sig) if refresh-record not found: ɣ = 0..kappa at random for i in 0..n: - blind_sigᵢ = RSA-FDH-Sign(blind_coinᵧᵢ, denomᵧᵢ.priv) + blind_sigᵢ = RSA-FDH-Sign(planchetᵧᵢ, denomᵧᵢ.priv) persist refresh-record = (commitment, ɣ, ⟨blind_sigᵢ⟩, h_planchetsᵧ) msg = Sign-Msg(EXCHANGE_CONFIRM_MELT, ( commitment | uint32(ɣ) )) @@ -902,8 +900,8 @@ for k in 0..kappa and k != ɣ: blind_secretₖᵢ = HKDF("bks", planchet_seedₖᵢ, "", 32) coinₖᵢ.priv = HKDF("coin", planchet_seedₖᵢ, "", 32) coinₖᵢ.pub = EdDSA-GetPub(coinₖᵢ.priv) - blind_coinₖᵢ = RSA-FDH-Blind(SHA-512(coinₖᵢ.pub), blind_secretₖᵢ, denomᵢ.pub) - h_planchetₖᵢ = SHA-512( SHA-512( denomᵢ.pub ) | uint32(0x1) | blind_coinₖᵢ ) + planchetₖᵢ = RSA-FDH-Blind(SHA-512(coinₖᵢ.pub), blind_secretₖᵢ, denomᵢ.pub) + h_planchetₖᵢ = SHA-512( SHA-512( denomᵢ.pub ) | uint32(0x1) | planchetₖᵢ ) h_planchetsₖ = SHA-512( ⟨h_planchetₖᵢ⟩ ) value = coin.denom.fee_refresh + sum( denomᵢ.value ) + sum( denomᵢ.fee_withdraw ) commitment' = SHA-512( refresh_seed | uint256(0x0) | coin.pub | value diff --git a/draft-guetschow-taler-protocol.xml b/draft-guetschow-taler-protocol.xml @@ -446,9 +446,9 @@ for i in 0..n: coinᵢ.priv = coin_seedᵢ[:32] coinᵢ.pub = EdDSA-GetPub(coinᵢ.priv) h_denomᵢ = SHA-512(uint32(0) | uint32(1) | denomᵢ.pub) - blind_coinᵢ = RSA-FDH-Blind(SHA-512(coinᵢ.pub), blind_secretᵢ, denomᵢ.pub) - h_planchetᵢ = SHA-512( SHA-512( denomᵢ.pub ) | uint32(0x1) | blind_coinᵢ ) -planchets = (⟨h_denomᵢ⟩, ⟨blind_coinᵢ⟩) + planchetᵢ = RSA-FDH-Blind(SHA-512(coinᵢ.pub), blind_secretᵢ, denomᵢ.pub) + h_planchetᵢ = SHA-512( SHA-512( denomᵢ.pub ) | uint32(0x1) | planchetᵢ ) +planchets = (⟨h_denomᵢ⟩, ⟨planchetᵢ⟩) msg = Sign-Msg(WALLET_RESERVE_WITHDRAW, ( sum( ⟨denomᵢ.value⟩ ) | sum( ⟨denomᵢ.fee_withdraw⟩ ) | SHA-512( ⟨h_planchetᵢ⟩ ) | uint256(0x0) | uint32(0x0) | uint32(0x0) )) @@ -457,11 +457,11 @@ sig = EdDSA-Sign(reserve.priv, msg) <artwork><![CDATA[ (E1) coin issuance and signing (exchange) -(⟨h_denomᵢ⟩, ⟨blind_coinᵢ⟩) = planchets +(⟨h_denomᵢ⟩, ⟨planchetᵢ⟩) = planchets for i in 0..n: denomᵢ = Denom-Lookup(h_denomᵢ) check denomᵢ known and not withdrawal-expired - h_planchetᵢ = SHA-512( SHA-512( denomᵢ.pub ) | uint32(0x1) | blind_coinᵢ ) + h_planchetᵢ = SHA-512( SHA-512( denomᵢ.pub ) | uint32(0x1) | planchetᵢ ) msg = Sign-Msg(WALLET_RESERVE_WITHDRAW, ( sum( ⟨denomᵢ.value⟩ ) | sum( ⟨denomᵢ.fee_withdraw⟩ ) | SHA-512( ⟨h_planchetᵢ⟩ ) | uint256(0x0) | uint32(0x0) | uint32(0x0) )) @@ -471,7 +471,7 @@ total = sum( ⟨denomᵢ.value⟩ ) + sum( ⟨denomᵢ.fee_withdraw⟩ ) check reserve.balance >= total persist reserve.balance -= total for i in 0..n: - blind_sigᵢ = RSA-FDH-Sign(blind_coinᵢ, denomᵢ.priv) + blind_sigᵢ = RSA-FDH-Sign(planchetᵢ, denomᵢ.priv) persist withdrawal // todo: what exactly? should be checked first for replay? ]]></artwork> <artwork><![CDATA[ @@ -730,7 +730,6 @@ knows coin | <t>where (for RSA, without age-restriction)</t> <t>// todo: document ECDH-EdDSA(priv, pub) (returns hash512)</t> <t>// todo: double-check incompatibility between h_denom and hash of denom used below</t> - <t>// todo: rename blind_coin to planchet, here and in withdrawal, too?</t> <artwork><![CDATA[ (W1) coin melting (wallet) @@ -745,15 +744,15 @@ for k in 0..kappa: blind_secretₖᵢ = HKDF("bks", planchet_seedₖᵢ, "", 32) coinₖᵢ.priv = HKDF("coin", planchet_seedₖᵢ, "", 32) coinₖᵢ.pub = EdDSA-GetPub(coinₖᵢ.priv) - blind_coinₖᵢ = RSA-FDH-Blind(SHA-512(coinₖᵢ.pub), blind_secretₖᵢ, denomᵢ.pub) - h_planchetₖᵢ = SHA-512( SHA-512( denomᵢ.pub ) | uint32(0x1) | blind_coinₖᵢ ) + planchetₖᵢ = RSA-FDH-Blind(SHA-512(coinₖᵢ.pub), blind_secretₖᵢ, denomᵢ.pub) + h_planchetₖᵢ = SHA-512( SHA-512( denomᵢ.pub ) | uint32(0x1) | planchetₖᵢ ) h_planchetsₖ = SHA-512( ⟨h_planchetₖᵢ⟩ ) value = coin.denom.fee_refresh + sum( ⟨denomᵢ.value⟩ ) + sum( ⟨denomᵢ.fee_withdraw⟩ ) commitment = SHA-512( refresh_seed | uint256(0x0) | coin.pub | value | SHA-512( ⟨h_planchetsₖ⟩ ) ) for i in 0..n: h_denomᵢ = SHA-512(uint32(0) | uint32(0x1) | denomᵢ.pub) -planchets = (⟨h_denomᵢ⟩, ⟨blind_coinₖᵢ⟩, ⟨transferₖᵢ.pub⟩)) +planchets = (⟨h_denomᵢ⟩, ⟨planchetₖᵢ⟩, ⟨transferₖᵢ.pub⟩)) msg = Sign-Msg(WALLET_COIN_MELT, ( commitment | coin.h_denom | uint256(0x0) | value | denom.fee_refresh )) @@ -767,7 +766,7 @@ denom = Denom-Lookup(coin.h_denom) check denom known and not refresh-expired check RSA-FDH-Verify(SHA-512(coin.pub), coin.sig, denom.pub) check coin.pub known and dirty -(⟨h_denomᵢ⟩, ⟨blind_coinₖᵢ⟩, ⟨transferₖᵢ.pub⟩)) = planchets +(⟨h_denomᵢ⟩, ⟨planchetₖᵢ⟩, ⟨transferₖᵢ.pub⟩)) = planchets for i in 0..n: denomᵢ = Denom-Lookup(h_denomᵢ) check denomᵢ known and not withdraw-expired @@ -777,7 +776,7 @@ check coin.value >= value persist coin.value -= value for k in 0..kappa: for i in 0..n: - h_planchetₖᵢ = SHA-512( SHA-512( denomᵢ.pub ) | uint32(0x1) | blind_coinₖᵢ ) + h_planchetₖᵢ = SHA-512( SHA-512( denomᵢ.pub ) | uint32(0x1) | planchetₖᵢ ) h_planchetsₖ = SHA-512( ⟨h_planchetₖᵢ⟩ ) commitment = SHA-512( refresh_seed | uint256(0x0) | coin.pub | value | SHA-512( ⟨h_planchetsₖ⟩ ) ) @@ -789,7 +788,7 @@ check EdDSA-Verify(coin.pub, msg, sig) if refresh-record not found: ɣ = 0..kappa at random for i in 0..n: - blind_sigᵢ = RSA-FDH-Sign(blind_coinᵧᵢ, denomᵧᵢ.priv) + blind_sigᵢ = RSA-FDH-Sign(planchetᵧᵢ, denomᵧᵢ.priv) persist refresh-record = (commitment, ɣ, ⟨blind_sigᵢ⟩, h_planchetsᵧ) msg = Sign-Msg(EXCHANGE_CONFIRM_MELT, ( commitment | uint32(ɣ) )) @@ -820,8 +819,8 @@ for k in 0..kappa and k != ɣ: blind_secretₖᵢ = HKDF("bks", planchet_seedₖᵢ, "", 32) coinₖᵢ.priv = HKDF("coin", planchet_seedₖᵢ, "", 32) coinₖᵢ.pub = EdDSA-GetPub(coinₖᵢ.priv) - blind_coinₖᵢ = RSA-FDH-Blind(SHA-512(coinₖᵢ.pub), blind_secretₖᵢ, denomᵢ.pub) - h_planchetₖᵢ = SHA-512( SHA-512( denomᵢ.pub ) | uint32(0x1) | blind_coinₖᵢ ) + planchetₖᵢ = RSA-FDH-Blind(SHA-512(coinₖᵢ.pub), blind_secretₖᵢ, denomᵢ.pub) + h_planchetₖᵢ = SHA-512( SHA-512( denomᵢ.pub ) | uint32(0x1) | planchetₖᵢ ) h_planchetsₖ = SHA-512( ⟨h_planchetₖᵢ⟩ ) value = coin.denom.fee_refresh + sum( denomᵢ.value ) + sum( denomᵢ.fee_withdraw ) commitment' = SHA-512( refresh_seed | uint256(0x0) | coin.pub | value @@ -944,7 +943,7 @@ for i in 0..n: <refcontent>National Institute of Standards and Technology (U.S.)</refcontent> </reference> </references> - <?line 958?> + <?line 956?> <section anchor="change-log"> <name>Change log</name> @@ -1052,87 +1051,87 @@ EajICvRouIyqtrcEMzOykwpB4zWRcBTUmNDG9k5MHim0O/jV3tPd4ycHXcgT 0q6iU5fyrCYkqYAZ7xIb6hAVZv2Ay7SaaCbY5UDsDDI0jaO+24dhqkmDgqbF aJUryYVJ0FHOC6vsYgPr1oOdXJ4KMBbKso8zbDUatE8LR4KH3ANToVaIZYLk 1+rF1nW2IQ445CLjYHvH0/uUNuq07YIVKC66Nkd6s73VfitHVyFmGaS9vVUA -yfpaaZ7w9GXWt83WOOa4q2JWY5ednEzLyPw28ToPb7N+jrDs0igCi3Ul1ZuB -Da6TFydZn+t03FUesYhUfmG2YAaOrUvCsogVcFU5WKxVgqXPpwx2vs607c9T -RMicElw20JWA17vPnx+cdU8OTg9OfnnQfX149nT/ZPd1nayljdmrXQj/yQxh -yoD4zD2FLE5rBgFZwtLqCRKSBhVUT2q/d+uyVZj23LdaTS58CN7TgpAOOoDz -oqQhzCQp0HIHbqu8CPRnTQrC2Jru8xpkyNw+XjrPo+g8m9p5x0gTYRg0LGZZ -Qq1xj4yhT5CD+pDA3oXs/O3LgSCikAO5RFIIP9V6iYJUzvbZr/ewOpZmCYvO -sXKARBeFT0tUKDpL5/vNOvMtDNnouwGJ3g8dUQPR9rgM4CiAOcEyozjDIJEC -FHhr2h0yhWosw7VrV3iBmyb4pYtO+0eWQEATeMKlAvpYHqGdzogMOLjAnf1o -aFZVAJd7o0rfgkgJ9S2vPZrTW8OUCvKWFsiqzbIxbkU/8qFUT0AsV1R4rMMw -TdsSZjWTlLPCU1rtKvpkN4i5681Ut9z7UW+TeimO57Gre/KgXrEAGPWxSJ2w -HtZUxd5aYw8bMQhXQujAjVHVm/AYzVtquUMMsQaB60+QTb6ugvfCCOSu17AU -AmovOx3dgWBMRjZUlNNWE6Mw3w1qQE9awGLiyJ//U6H8R49UpZHGq65awpAD -HtO5seVVxLoMwqmYl01o/ScQ2/1EyRIb2T3zO2rL9x1W1ONejVEBEag3GIvz -ToquqDNADzDxGS7OpXQGJ9DzBEWXaxeSTbRWqcrVuCs6wgAtKVAfcB3gCS3c -kYNrWB7nEwGxgHxyI5Ouf8q90BI63w5tZinrFgK1SOjSXs6KJc0EtGpMlqWc -UK1oqyvMSLo0+mJVgGsk/0fgOYUimGXGzzR+BUYLU31m/+uJgwc1WJMdP96D -/1+dHBqJ/jKcbZph48r36ml0zsMfP9RMwDuooa3K1XWhl2zTeiXem49ZvrGi -wZKWiilNomzSvBIU9r0PTbLAki8LamjwsWniIooRbQVnNGO+aA3tOgpE2auw -rLepQ3ehRujkBaZ1w84hC6h4uUqNVo25bCrLW8qCsnI4wiGvoQ83GbN8Y81p -Xk8ZYEbaRC1WBvGxyxFFrQz+ZVTiOsqwncdLIn79LCNX4LKsZCy4ZWuZL3zu -SAGWSqMuFisFoC3f6kjHMgRuMuanz9MsFhs1YmbUiCEEigJ/MBOL4LKQi1vN -cJ+2qvxVBh+2skwAdeHHvCv3Vsta3+bWw5qlz5EwcOmM4ll1xkm4EZ0Riu47 -zF4AiEVuOYZZUql0zXnmJx4tLGlL34YB5NzhVl7YbIub3kR6QlE27crC4izm -67R474YzQejSnrGG9TS6wCIyHTMaqKTW3F42zGhTSxrRkSSOL6cA/Mb+VG4q -E6ShBVqxV6xu8dDF/G6E/TgDlzbZZJA/QLS/kYUqt9rAioJa2I1lCVz2hoVs -WcaGwbBP3MSNR6Lkpjgl4kpuQGbkMRe5rwHT7He+l9EhJ8ilGkpYFjhaU16E -zTHjCdzaKEVi3EVWq5qvZrsM1utsQ3Xk4LN8h5Is8eYyp3eJ4RsVhhmkwx7k -vEA3LqVJfbU0vh0zBhViSFIow9G6kToINOvrj1LTwzSUXOrgSoukAgEqGEjp -cgIwLcRjWP9y+uJYBwm1uRLa0cEJrhCcdfdeHJ+d7O6dIboafL5sWUim5uqW -i1x+rmd3iWxFba0YE5WLa2UqSzLjosvZi/0Xbbkk4ghosb2FTqXQjR8tcO8J -D8R7CGQy2mF7IOKn6q6eTONKywMJC+QrYgjcJJZBDnTkxuf7fpzOaCVlvhJl -z1XK6qxUM8Aqr4mPRbvbZOm1VDPF/T7d/YOXL04Pz+rScdgGNUtlTUt5FPVa -E1nd1NOTqvi+XJzSDTWk1gLzZkkfiq2Mqsg3rFC+lJGJBq96iJvjDCkoz4GO -iOkKpSHp5tJMXRKyRsVyFdChDVBQVyhgWK2T8/4wx526HMVYJ81jd5QktdZd -Z3Nho1AxLZZql1dB1IznE3fWp/3V9K4kzpLZpB8F6vRNk9xYGRrclDvhWk7Q -QdCNghNz8VUxOLGhWJ+10avBBDI67qkqba7aAllnMHv2W6xaKfMufYbaI2lu -itQxxFzIOe8Q8mK2IlPDJLeoeXc6rFghk433RaP56HyhvXm5++ujA/j74tnN -zOOigNBYD70mBteweapqK6fPru6p2pyxzOx6nhacNMK3M4HZsyzVRoQlbpBE -OjbxfNxxjad9UT5kYEiFU9qjfxEKbyzONet3QmnGzBcFdQVy1ae0PVB9JS2v +yfpaaZ7w9GXWt83WOOa4q2JWY5ednEzLyPw28ToPb7M+NlauS7Quriqpvgxc +cJW8OMX6XJfjbrFT1U1+YbZgBoatS8LRbA4cVc4V65Rg5fPpgo2vY8huwKPZ +tzA97zBdA3i9+/z5wVn35OD04OSXB93Xh2dP9092X9fJTtqYt9qFwJ8MECYL +iMvcU8jftE4QkCVsrJ4coVhESc8R94O2LluFKc99q9XkkofgOi0F6XADeC6K +GcJAkuosd922yohAc9aiH4ysaT6vOYas7eOl8zyKzrOpnXeLFBEGQcNidiXU +GffGGHoEuacPievtS83fvgwIEgoZkAsjhaBTrZIoSOVin/16D2tiaZaw6Bzr +BUhyUe60RF2is3S+36wz38KQjb4bkNj90BGVD22FywCOApgTKzN2MwwRCb9B +SNPakPlTIxnuXLu/C9wowS9ddNQ/sgSCmMATbhSQx5II7W5GVMCpBe7sR0On +qoK23ANV+hNESihueb3RnNwaBlQQt7QoVm2MjXEr+pEPpWoCYrmSoulXoZeE +m8OsZpJyVnhKK1xFP+wGMXe9meqWez/qrVEvxZE8dnVPHs4rFv2iPhamE9bD +OqrYT2vsWyMG4eoHHbIxKnkTHqNhSy13iGHVIHD9CbLJ15XvXhiB1PUalkJA +7V+n4zoQgMlohgpx2l5i5OW7QQ3oSYtWTBzz838qlPzokaou0njVlUoYcsBj +Oiu2vHJYl4E3FfCyCa35BGKLnyhTYiO7Z35HXfm+w4pa3KsxKhoC9QZjccZJ +0RV1BugBpjLDBbmUzt0Eep6g5nK9QrKJ1idViRp3QkcYlCUF6gOuAzyVhbtw +cN3K43wiIBaQT25e0jVPuf9ZQudboM3MZN3inxYJXc7LWbGkmYBWjcmylJOo +FW11VRlJl0ZfLPO/RsJ/BF5TKIJZWvxM41dgtDC9Z/a/njh4OIM12fHjPfj/ +1cmhkdwvw9mmGTaufK+eRuc8/PFDzQS8g7rZqvxcF3fJNq1X1r35mOUbKxos +aamY0iTKJs0rQWHf+9AkCyz5sqBuBh+bJi5iGNFWcEYz5ovWza6jQJSxCst6 +mzp0F2qETl5gWjfsHLKACpar1GjVmMumsrylLCIrhyMc8hr6cJMxyzfWnOb1 +lAFmpE3UYmUQH7scUdTK4F9GJa6jDNt5vCTi188ycgUuy8rEglu2lvnC544U +YKk06gKxUgDa5q2OcSxD4CZjfvo8zQKxURdmRl0YQqAo8AczsfAti7e4vQz3 +ZqtqX2XwYSvLBFAXfsy7cj+1rO9tbj2sWfrsCAOXziieVeeahBvRGaHovsPs +BYBY2JZjmMWUStecZ37i0cIytvRtGEDOHWjlhQ22uNFNpCcUZdNOLCzIYrZO +C/ZuOBOELu0Ta1hPowssHNPRooFKas0tZcOMNrKkER1D4vhCCsBv7E/lRjJB +GlqUFfvD6hYPXczvRtiPM3BpY00G+QNE+xtZqHKrDawnqMXcWJa9ZW9YvJal +axgM+8SN23gMSm6EUyKu5AZkRh5tkXsZMM1+53sZHWyCXKqhhGWBozXlRdgc +M57A7YxSJMZdZLWq82q2y2C9zjZURw4+y3clybJuLnN6Zxi+RWGYQTrsQc4L +dONSmtRXS+PbMWNQIYYkhTIcrRupg0Czvv4oNT1MQ8mlDq60SCoQoIKBlC4n +ANNCPHr1L6cvjnWQUJsroB0dnOCqwFl378Xx2cnu3hmiq8HnC5aFZGquYrnI +5ed6dpfIVlTWijFRubRWprIkMy60nL3Yf9GWyyCOgBZbWugkCt340QL3nvBA +vHtAJqMdtgcifqru6sk0rrQ8kLBAviKGwI1hGeRAR258vu/H6YxWT+YrUXk1 +R5UF6qxUM8AKr4mPRTvaZNm1VDHFPT7d/YOXL04Pz+rScdgGNUtFTUt5FPUq +E1nb1NOTqvi+XJzSDTWk1gLzZkkfiq2Mqsg3rFC8lJGJBq96iBviDCkoz4GO +hen6pCHp5nJMXRKyRoVyFdChDVBQVyhgWK2T8/4wx526HMVYG81jd5Qktb5d +Z3Nho1AxLZZqZ1dB1IznE3fWpz3V9H4kzpLZpB8F6sRNk9xYGRrclDvhWk7Q +QdCNghNz8fUwOLGhWJO10avBBDI64qkqba7a9lhnMHv2W6xaKfMufYbaF2lu +hNQxxFzIOe8Q8lK2IlPDJLeoeHc6rFghk433RaP56HyhvXm5++ujA/j74tnN +zOOigNBYA70mBteweapqK6fPru6p2pyxtOx6nhacNMI3MoHZsyzVRoQlbpBE +OjbxfNxljSd8UT5kYEiFU9qXfxEKbyzOMuv3QGnGzBcFdQVy1ae0JVB9JS2v /JThUA8qaoRL2hZru7KxjDby0Hbl571sWTAABVlc1b58Y/WYquWNcnqM75Vu -/m3m9JQpNvtYRHfUTEx8Fm0SEylGrnoLWbYU54oazd3MthpuMR+uubtMUY7O -Q91Weey2iwPMNiJu0zrcfXVsdXEAkx9Nxb+f4sB+hfEw3TuqGYWIzHDeVwYf -C4nSXCL1QXQg00K7bJlrP6dk6cAgh6FH5u6OYoKrp9YwUt385npJ76IlbjyW -awZTfrhkY0gpyF+5O0T2rLaGsNIZLl3skMkQFTzMAaF/2mFQgWce9C1ODu46 -C1qZ/GipLmQ/+d1F6Y+a9I0TnIow0dhwoNKbuklaihlvcdOC5LQAEcdp1M6S -4r6FIoxjwCgIJU4QeEaxZyXQt5cFeNLTOJ9AZTJatM1pjgn+hT2n13qXJOj1 -48OTo6JIlARCM9ukstwqVM3dYgWpLBFVvH+/VoJTsT+pyD+1QakgHlWb0Qoh -8ZyhQle1X+WqTMN9w1rc5+CI9idVDFlairhjflRoZzFcmU/iTvgQ3O8Y3zIk -rtZI4n42x7BU8gNW/lqf2w7WVu6/Z8a6PqE74eLtP+sMfJMxyzfWaLSgZXl8 -1sQ5zK2SLVrKJBNfVd0i61xfhq0UTNoNXX2u5mdwqkZx5Xrpz8idTNy81iqP -noN83PoZm2viV4HxonVTZv/5jwvTIvrcSW60Qv71zgH1fj7+jo7yr95Hc5Mx -yzdWTnBhS3NY1hTHQZx5jVuibpOJn2KFkAoM6jwJKdFf/+M/9R6CL6w619EX -WuVTs7rdisHdaAbx7h+H0PKW5RurWuQtr3kIbf6E+sEeZB0UGdkiNsV0Ak+Y -iTeRYnkBX91daGqs2UFCGU2mIG59P8Cf5+jz9ILzUG2YJsOt3jMn7lBNu8+D -6MLoUy6O5FvWKbmQHq1OK3bUlR8aG9ZxQ0L0o2Vdtdso/7Q9GnoETS4fzhrx -tIs2ooslE1xVpPKkofOs0E45Vk6vgyWwbhp1z93p1O3mTRPsSWVD0I8RgS3t -L+8Be1UdCNw0RabAAaBngvsRiEfiQJN457JxwoneupL/+EFdvlO1zsqIASge -Z6C3oMhwMz9sIYCKWNNJK/6uS+9iz0ETgC0CijC3K1+ppQG74uBaIjowLFQl -bZBFOYyFpP3Lnz4KvDCkvWo3Pxg7TQrBonl0Mg+JSofdqrguk6kN2cwRVWvi -7Ua9FF/pI4F1dv61KvScy0IPiQYWexZLRHksBebIzS3OOZ/hqAUkIa2DW+HX -+JJhxuZKS6yKy6UTcBXoiEQqGeMOfsn5jmkIKpqo+YtaA9O6qRCtPhpoDqFP -Bi46Dlg8EFjsc6N/jrSpGFVQSNBH1NoMrHVzvH/d9tWHCefImNssjfLic4F5 -36WjgQqZclXHPOOl+7/BMS/ZR/HgIal0Z8E5LK2C0EhUjMQhzAaNSXUyKdJV -Z6CufUIqNxMGQgW1njsPpiQTLmm4yiMIi46ZJdIU1FhF6Xbd06KSzEXmXecc -piZyvcqCZH0MjhadzqMa69HBc127MWgoiaO8cUW1VdJMYV/gZ1UlyzCDVMUq -HIaSMkGpTqPRMM5BmUGDCFpMr22RPzh4Cq4i9MBGkLNe6gPWShLNSr86yTVX -Zs9r7EaFvVReVzZbnbxcWbM1CrZGtVbIRV6oJaHNR/Jwd9LKA6dricpnO46q -SUJS9Iu7tQ2EkBqoI5XdIKcueosnZr07L3aLZ5XOu8K//pys7xe1jV/A9ixY -UylXbKnM0oV/KPUBSbJWWLGAYST9NQvi4+JTkuchvlQLWf7nP+IL8qVQ4Jk7 -EUNWS8e6x28/mr79oxk/5Ed+Cyh1ioUKnOF8ulw3hQj6XV3kX8gpKbB//mP1 -WfqFyxcFIy7j+iQeNAO/31SNuu7Up9djUJmmMWgzYeVFRjbE3zMYgwFZ2dqo -9WAnQDk86trVv6S5NGWoLHjleYPagGpscCJ79+kUBTm63sJDWRIAKsBXI3N0 -ooUT2fPGi8zyOfuqA8OiZJarWjCFQlqxmHmmExa9rOGLFxagCi9SWFOI11Ji -wFa8479rqomgC1FhNY3+kan9I1P7e8/UiqFYHodVBmGFCOQXtxyCrBWDqFAv -D4M6xrdfGO8zis8dZQM/xVGVXI1hCLvR+XJH8ymvv/j4l3XegCGCiOKrJj5W -iuIaW0o+lneVKBwWvQ3jo7HtZtELMfRrAz5Kwqhd9XLVHHc149I5TIFeA6Zc -949qxR1iMLHgDhf5ert8OojAJ+BTvCg9fS1epJVGjrhiLzOQ8vz1GRdbF840 -MxfxFzULgrlmQVBohj+MmcVY7N7DV7F78lRVIn8ueZ9+LvkeO8S3PpchjqMQ -f1gR1z/6LmTC+Ius4m0OQTTCb7sDjDtAbEfid7mv2uLHfbnX2RgCAfnGh8I4 -9I41+m3dC/r1PfoFJLG/i177Ll+aK37Cmj3mHv1+8hH9iFSMh+msAy8b5G8Q -O+EJd+PBmNmPjh49Fj9+lp+jw7eN4pxQ+Dhe0I6OpGH9PzfAlV4YfQAA +/m3m9JQpNvtYRHfUTEx8Fm0MEylGrnoLWbYU54oazd3MthpuMR+uuaNMUY7O +QN1Weey2iwPMNiJu0zrcfXVsdXEAkx9Nxb+f4sB+hfEw3TuqGYWIzHDeVwYf +C4nSXCL1QXQg00K7bJlrP6dk6cAgh6FH5r6OYoKrp9YwUt385npJ76IlbjyK +awZTfrhkU0gpyF+5M0T2rLaFsNK5LV3skMkQFTzMAaF/2l9QgWce9C1ODu46 +C1qZ/GipLmQ/+d1F6Y+a9I0TnIow0dhwoNKbuklaihlvcdOC5LQAEUdo1L6S +4r6FIoxjwCgIJU4QeEaxZyXQt5cFeLrTOJNAZTJatM1pjgn+hT2n13pnJOj1 +48OTo6JIlARCM9ukstwoVM3dYgWpLBFVvH+/VoJTsTupyD+1PakgHlXb0Aoh +8ZyhQle1X+WqTMN9w1rc5+CI9idVDFlairhjflRoZzFcmU/iTvgQ3O8Y3ywk +rtZI4n42R69U8gNW/lqf2w7WVu65Z8a6PqE74eKNP+sMfJMxyzfWaLSgZXl8 +1sQ5zK2SLVrKJBNfVd0i61xfhq0UTNoBXX2W5mdwkkZx5Xrpz8idTNy81iqP +m4N83Pq5mmviV4HxonVTZv/5jwvTIvrcSW60Qv71zgH1Tj7+jo7vr95Hc5Mx +yzdWTnBhS3NY1hRHQJx5jVuibpOJn2KFkAoM6gwJKdFf/+M/9R6CL6w619EX +WuVTs7rdisHdaAbx7h8Hz/KW5RurWuQtr3nwbP5U+sEeZB0UGdkiNsV0Ak+V +ibePYnkBX9ddaGqs2UFCGU2mIG59P8Cf5Ojz9ILzUG2YJsOt3i0n7lBNu8+D +6MKyrtptlFza2Az9gw6Wj1KNeNpF7e5isQPXA6mwaGgrK7RTLpHTy1sJrJtG +3XN3OnW7edMEe1J5DPRjxE5L+8t7wF5VBwI3TZ8p0A4okeBOAqKuOH4k3pBs +nEeid6TkP1VQl29ArbMyYgCKxxDonSUyUMwPSQigItZ0Loq/69Kb03PQBGCL +gCJA7coXYGnArjhmlogODNtSSRtkUQ5jIWn/8qePAi8MRq/azQ/GHpFCmGce +dMyDmdLRtCquyzRoQzZzRL2ZeLtRL0VG+gBfnZ1/rUo057JEQ6KBZZrFElEe +S4E5cluKc85nOGoBSUjI4Fb4Nb4SmLG5ohCr4nLpvFoFOiIFSsa4915yvmOq +cEUTNX9RJcgPrilEqw/ymUPoc3yLDu8Vj+8V+9zonyNtKkYVFBL0EVUyA2vd +HO9ft3310b85MpZUaNkpvrzn0kE+hUq5GmOey9L9f/LRLNlD8ZAgqXNnwdkp +rX7QSNR5xHHJBo1I1S0pzlXnlq59qik3EQZCBZWeO8OlpBIuabjKgwOLjoYl +0gzUWEXBdd1znZLIRdatf2pSk7heZTuyPgY0i87TUV306OC5rrcYFJSkUR60 +okIqKaZwL3CzqvpkGECqPBUOMEmJoPSk0WgYZ5dMRy8CDdNfW+QJDp6Ckwg9 +sA7kppda/7USO7M6r05fzZXG87q4URUvlcSVtVYnJVfWWY0iq1FhFVKRF1dJ +ZPORPNxRtOJ46FqC8tkOj2qCkAz94m7tAiGkBupIRTeIqcvU4olZoc7L0+JZ +pdOu8Ks/H7v7Ra3iF7A7C9ZAyhVWKot04R/KfEByrJVVLDgYSXrNgqi4+JSk +eYgvvkKG//mP+BJ7KRJ4Rk5EjtWysd5h2Y+mR/9oxgz58dwCQp1iWQHnN5/c +1k0Rgn5Xl+QX8kkK65//WH3mfeFiQ8F8y1g+iQfNwO83VaOuO/XpBRZUVGkM +2kzYd5GFDfEXB8ZgPFa2Nioz2AlQDg+mdvVvXS5NEyrLU3muoLaLGtuRyNZ9 +OkVBiq63TFCWBIAK8OXFHN1n4fz0vOEik3zOvurAsCiX5RoUTKGQSixmnul+ +RS9reOGF5aLCCw/WFOK1VBiwFW/h75pqIuhCVFhNo39kZ//Izv6es7NiCJbH +X5XBVyH2+MUtBx9rRR8qxMsDoI7x7RfG24bic0fZv09xUiU3YxjBbnS+3Ml8 +yosqPv5lnXdViACi+FKIj5WCuMbmj4/l/R8Kh0XvrfhobJBZ9OoKfcD/oySM +2v8u17dx/zEucsMU6CVdym3/qNbGIfoSS+Nwka+My6eDCPwBPsWL0tPX4jVX +aeSIK/YyAynPX3RxsXXhTDNzuX1RsyCYaxYEhWb4s5VZjGXpPXxRuifPPyXy +x4z36ceM77FDfCdzGeI4CvFnD3Glou9C/ou/lyreuxBEI/y2O8CYA8R2JH41 ++6otfnqXe52NIRCQb3wojENvQKNfvr2g38aj3ycSO7HopezylbbiB6bZY+7R +rxsf0U88xXjszTrwskH+fq8TnnA3HoyZ/ejo0WPx02T5iTd8FyjOCYWP4wXt +vUga1v8DGlTYQrZ8AAA= -->