Skip to content

Instantly share code, notes, and snippets.

@hellman
Last active June 23, 2024 12:49
Show Gist options
  • Save hellman/eb4b635b32d7f80e16da7e75f93d36df to your computer and use it in GitHub Desktop.
Save hellman/eb4b635b32d7f80e16da7e75f93d36df to your computer and use it in GitHub Desktop.
Hack.lu CTF 2017 - McEliece
'''
Attacking McEliece with Generalized Reed-Solomon codes (GRS), method by Sidelnikov & Shestakov.
The task is almost the same as The Russian Attack from Sharif CTF:
http://ctf.sharif.edu/blog/Write-Ups/SharifCTF-6/Crypto/08.%20The%20Russian%20Attack%20(500%20+%20300%20pts)/
The only change is the field changed from GF(p) to GF(2^8).
Here is Sage analogue of the GAP script, because finally Sage supports GRS decoding.
'''
from sage.all import *
ct = load("ciphertext.sobj")
pk = load("publickey.sobj")
k, n = pk.dimensions()
F = ct[0].parent()
M = pk.echelon_form()
for c01 in F:
if c01 == 0:
continue
alpha = [None] * n
# we can set this w.l.o.g
alpha[0] = 0
alpha[1] = 1
# First stage: get alpha[k..n-1]
good = 1
for j in xrange(k, n):
b01 = M[0,j] / M[1,j]
if c01 == b01:
good = 0
break
alpha[j] = c01 / (c01 - b01)
if not good:
print c01, ":", "FAIL"
continue
# Second stage: get alpha[2..k-1]
for i in xrange(2, k):
p = k
q = k + 1
while 1:
bp = M[0,p] / M[i,p]
bq = M[0,q] / M[i,q]
A = bp * (alpha[p] - alpha[0])
A /= bq * (alpha[q] - alpha[0])
if A == 1:
p += 1
q += 1
if q == n:
break
continue
alpha[i] = (A * alpha[q] - alpha[p]) / (A - 1)
break
# if guessed completely
if alpha.count(None) == 0:
print c01, ":", "Got full alpha."
C = codes.GeneralizedReedSolomonCode(alpha, k)
D = codes.decoders.GRSBerlekampWelchDecoder(C)
try:
res = pk.solve_left(D.decode_to_code(ct))
print " ", "message vector:", res
msg = "".join(map(chr, [v.integer_representation() for v in res]))
print " ", "message:", `msg`
except:
print "no decoding..."
eJyF1EtwFEUYB3B3syQwQFRAxYAhIGZXhSUJPgIqj0gWzEoMiyMCxnHZ7d0ed3Zme3Y25uFKQPNY
BBQVKQ8+Sq3SKq9WWR7Vi1XeLA8etMry7c3y4FH9778zGg6UNZdf99eP7+vumulorpotimTZy9cc
UU0WfCEs3bCEI8rCDYxytiSsFAIH2T+ou62icIVv56y8cKvCGus1VCShF6sGfi0X1HyRLGRzgedP
GOHYhbZVcyt2ruQIQ0WvOMfxvFKtYhUd70TWMVSLafyXg4rNZNSSdFs6NqtaEzKakC3m8pTt2oFI
2cLJqzbEl8rWhcV92y1Wk7YbiKLwdT1hQy0zo/09GG2Y0cl+tXzxhIrnTLhe2c46i2gVC33jeo3w
gNSK/5/VjFk5z9V1er4x8m8sg5ChVrKMZs5ymRnpQ0btZmR8Rl09bMZwIa66xoxO1WV7M9qL6LXz
gVpVD9TqjFqDgcONIKOuG1XXX1ZygUdiXVZ/83oNHKOhbgjXWhtueaNcM5dRHZKR5qmsk7prvezg
t55fh2g05mYz6iaztWiPZX1PdZqdU/GKLwr2eHxnV3wyvqUr7ouK32xg33g93GFDeikS76qrjQmz
VU9Qm8zIpBlrDlc3my0YrjbXAnVLRnWnpxvDgYqjzERG3TqqbrtydSJ8lkzICF+YtehVLMQGw2u7
XXanf0IZW2RTx6Ct1FtQkjoEbaN6oB7qB6iX+gbqo/ZD26kPoTuoAehOqh26i7oE3U0NQf1Sj9wG
76BaoJ3UL9A9Uq/+Onwv5UP3Ub9Du6jV0G7KhvZQR6G91D5ogHoTul/qdS7C+6j3oUFqD5SiPob2
UzHoAPUa9AC1DhqifobS1BHowYVs2+CDlAENU/PQQ9S30Aj1F3SI6ocyVAo6TBWhh6XOJwqb1CfQ
I9RV0BFqDHqUMqGjVBI6Rp2FjlO7oMeod6BR6hT0OPU1ZFET0BPUCJSVQ1Ln9iNaJ6g/oBzlQnnq
M0hQX0AFKg8VMV/3x9GS1GHIps5BT1K/QSWpvQp2pD6HlXCZOgm5VCfkSU8OYLw+wbfRU6G2Qopa
C/nUaahKbYcC6jxUo36FxqjvoacoBY1T70IT1BJoktoNTVHvQU9THVBdlujj8DPUR9BJ6k9oWuqX
thc+RSWg09Qg9Cy1A3qOWgHNSH2PEXiW+huao0aheeo7qEF9BZ2Res9u+HlqM3SW2gSdowR0nvoc
eoG6AL1IfQpdoCzoJanf8Rvwy9SX0CtS/xs+gC9SB6BXRXp6Hj/jS8l/ACTDlyA=
eJyFnQmcXVWZ7StjJZV5nuepyDyReSRkujtDZajMYyWVVCWVqlSlMpMEREAUx8aJBkFUGlQc2gEe
CggItt3a4oSAKJPY0qDYar9WaMxbe/3P2Tf+3uvf++VH1a1z7z1n7+9b31rr22fg6pb7ju09WD3x
yN7mptpT2a/dBw9Mrd69v7r+WHXZ8fqjtfsO11Xv/r/e2n1icllji/L/1/ePNOyf+j98v/jW7hNT
yhpblodFq0ta72xsVV648eLFi6EirAnLQ6dQFvrrvxL/6xRWhhXhyrDef7XOtpaERaFFaMXrwkP6
cuHb8cdH44+H4774VFvtc1XYGJZmn7wY3y/++Ez88Uz8cXv88YviF9uHozrs1nDMf3X23i992aLw
4fhrXOgcBnj7UP23UuNcrKPVFK7xZzTIoR5N4Xl/naP8Lv54Jf745/jjj/HHd+L7uwrfiK+fjD++
Ejec0v6HFG6If/9d/PFE3Dit8ED8taBwX9z0Wny9u/Cv8Vd3D6Bj6MM+Pxi3XR6m8pkToU8YGToV
Ho1v/ZPfKnw1/urtvwrvij/eiBs6h7mhR+Hf499PccCr4+u/jz/+K24YVXghvr4rvl5M8F+Pr7cU
7o2vb4s/vhs3LAsDCx+Pf72b2UwIXcPJcCSsK3whHyC7jXkIJwvPxl9bCz+Jm26Jr5tCKdOPMy+8
J99V4ab44x/ywBXujJ9tFTY77IU74o/PM+erwtrCp+PLdgwk5jrML1xHaFoV/hI3vuCxOhqF98Uf
74wbJviLhd/HH5+MP16MW8vZ8In44wPxR4RB4bN53gS2ksK34l9x2AJvF/Ze6vkU/iVF+smEwbeN
o8KP46/6wk/jr35hbVhaeDq++xiD/358/YP4w7PZGOpVKlcU/jv+MbLwy/jG++OPm+OG1oUPpTJo
KvwKaDmfMVehOvQq3JMfPjTz+svxx0fij/8Vt44Nm8JCQvbr+HcvR1sbu5OkZYWfX3TBbi28FT8U
8xk2K7VjCj9L2FtFJHzQ8wLy/44vzurfSKJxa/xxN6mPeKFKNhPcuFtV4OjQIVQJkE1gM4D0LhTt
6yn2X2Iqxn1EeNhe+FH8NadwrSFd+I/4a2jh3+KvfR48Y7gnBwsx+2GOemLqlE4tfCr+GqLMPmj4
hxB6KkIrNKzRBM6hXll4Kb5+b3zdN4wlvAv1sXau3tBS4DF3DCx8Ls+VRxy6hZZMb1+4jHhvdegE
g1X6N8J4hQKMpunOTJhC2E8VHo+/JhPK0rBE2bqBY/c0wMV+p7S1VBO4hmh8w8PQPBaFCmD8m7hl
f+Svwp/iy5mOTDhNlMw4l4VahxHWdKlfD7acB7NMG4D9jot5VU6E5FxwawSbuKfCb+OPv8ZNda41
11Toy6bV4YzwPU0I76l6+GZ8+2WwtwGsmQZcEKaVIJ4NiqlzM5/wl/DJyC1hcJgH3bwBDjeG6eLI
eeGMaS1sl7KcdkJE4ecFehPPtNAmzOBIj+cYpnCNi3+MnzlR+M+LmeQobebVjyXsDzODFx6Jr4+I
Qt+ML9ZD+zHACN4sNjgeP8kDgQq8J48vU32AbPjXUcHaQKoI3UD05XDpx3IICz9xsKFG0TzMuCOx
CRh/SCMsg+uctiuFtIVhhCq4OewpfI1MGgeLqIH+MPB38qJAGdro+B6iqdMltkC1+dsEqE0M/s28
vsJZ54dvX0YY5/PtmD7KuMREpwHclTbtMalLYbdTb/cDiIWOIlVQD8bGhrmEdoKqxNTw/MWMHMM2
/TvK0V5mdx0Q479POW2rMAAlsxUl1RFWPhl2GvUqnOUaSCQWH0H1fXv8dVx6N8PqJ4V0onaiN6sk
NBbOqnBYkjCKVMctCIvVrytVZN1fq90bwA7EQlyNydmzvyGHpUJ4GxAfIVLzIcZxyMNhBVOLMAoH
w2Boe2yYqkEuI4+OztvpoNO1k+P+GKEoD+fxOGXIzELVZW8R2xLZG4vBbkmkdb+CQmumoHpowEbn
cAV4GuGOHCB2OSo4dsfFrA/r9PIWsBUlqvC9HOs68qJL7EgTo/0lKT9kfQJ1tiVRbsJskZuyYskU
6K5PKZ8Aihczk7nC39dThT130eQZNTlM1NQfSChdqwJ7bx5zTagv6ulZLBZJDHMGw6ywQ/OoAz7f
YVYTVBKuqxeYyWrh+88kxs7FJWq2yaJ4VLx6msgNCJMMTDOycOwUz1NBeQdX4BQWwRGWGiN+L0j9
dYLjYXlDm2EL7wERnY98bfHI4suV4gJT70/zH6GAEbSwR2c9yWQhsXa1tVOMlqrKvpIjlqo2vsbg
xTyJ86YPXEC0aUJcmTZ+Iw1voGL+EcpvpyqiHeK5FCLbGE7LAMQciUkGE/EWJNpYmceOrZpjSda8
sIZiMVFtUXn9iVyPZMoxzbDIMRxIGdVfqyldUHgm4tAfSvmergyfC3PCoVCNNro+j1BfYyheu4rW
0EE71bl1dYlG8mNgOpbkbRX72le8g/yOE3y6S3RPYjRMXDuFo54y5ytQ03pmP8rKF/Yoe3YnFvT+
MuvW3VcTHEuwsHZLp1FLR6Wdp4wJmlxdjim2rz0XFRN4+92WKOdEFGMcZWBrFn2YHPSCwhdBzXnc
xFj96xkmizy/kn9ULcdrRNilZ6fi8RcEtK6hi+zEzfm4FYJSTRlXBSB7QZdL8TkmvQbF4448c9Ro
b2Y5R2baMbUw+7Br5SmvMIDY31nVr3ubkfIGhzQ4Q9J9iTufftq8Ebgu1Lyi7u8N88V/I4SfpXp7
BbplnRwiIbkrVRi1rA/OCQ0oXpP47wlwcxjy7e+KoQVqZOyzhPYKIaUzOZ+mAlvOBFybX2av6820
FLhV1h3I9Wmb6+c4YFqJ+7kMwzNJztiIWwi4V0PJ0/i1FYg7ng+Qywxt28M2ojobgXeRVSgTboUb
IIMz8gVN5P4IVW/P05V2xmrbEYHe5fhgL+czoB4q9/u8FyzNY+z4R3lVQJRLqa4OImhPa78c6wKB
0Tw7ANlLtjw0SqePYp08+BaIRxTTcAFNdf+3DX/wAmkcLHreEvaTR+Ngi5Sxp+jpEAB5gSJdKxLv
gI0KRKlE5tpt1H6aslvZubNWTeti4dqgbtNt2D1kyMP+t7yU2NcmwdFfLFVcWyFHtqcuByezyqjG
ODvlJ0VyQxWR8TRUjrH1vJsYZqRMhwt0nV7cA7rOOziKfQ8RhKM/gYhMgrmOI2jRb9umQ5k7xEJX
qLpMpCsVnfPC0TN5vmk/v5Jq0i6xDgrsLfoo8tBgPvrXPBLIyxDG/QMCWqqCNTbXqktvyyAclhZh
EEW8i0EdwvhYg8YVDTaMfl6zn8hBh+Ha3spBklpS7IPtbwkQtCnvjRhMh7pHaTiW46bQS/7I9bzH
Rwvt1bcMZCfO+3Ac5bdyMFM4LzFxrxFskya/zYue9HHntOVz+TCIlPsFM2+B1Ayhce0vR7BFmBwr
P3UTZeZalDHXbtZLdB6Of/YlMUZpJSiyZTLDXhAfnEbZf5VSNSNs8Z5YQaihOueKvIxN05DNh/mq
Qmo/V9K9S77SWvAMIPJQ9snaLRPytkKh+9QJGVXtxEbfpzTcNbpAzSAbQye09Qh4aa/AmKd66Rh7
lMb2qiOrxvtzSEaMQBYLkIXric6m4mSlLJUSitmKlM20V3/s2NuoYFqIouPiX61o2cVykMbEpR5l
Gk+4NAxTML2WZi/8zYQwG5IKMrs8W9PjO4eJaFcK11QWKxA+cx3b7nzPM8RZmFuOqvCeI5ltMVsG
wDl6/m2EpFGY9HpBvzCUftvl0FEZvTEHd7gKx3VTPli5iqCInabYVzHWhxNOTa7jBRRryU/zCEgb
KxiqBfXN/E11rCvweIyWUjYw+mgnTtRv8xCRHSf8rfxjwMkFthB8OSoeMw26MjeOMjsQ1uHbq0T0
LoFdKqRf5VGUWypTDtdIqsaGfky2Fnl2jY0WuCaL8naIRzIzZM55PR+G4riKNumoOMV8Wq1S8NqW
Gcl90EuMaq2Y/2OpmD5C6kdKEPrLVAyRS9jCrvZqV15r2wkSe4Ioa+EOYeXTed5MNkDEixwdCOl6
as0xfir/JtB8PR3eXzghmHnSBUG9F9Rm3zZW6u5MOoqrJXwWtvcRlB0i8BryYz95UlOr1QyOk4QX
yOVaDK7tze1x0xVxZR1UbiAZ0beUIEhmO4tsazUZVcQ51hurCs/l5SM+MCZsNbrT7O9UkloSls+n
ST+Vw9dypPnVhnJmaN0fJSLco/aoVPEfCpBd3Z20vZOcwitEe4w+sEiU1E2JOk5IvPjQRAUPkwfz
At5iPKgFaJpCEbSTo2GmvKL7qDkS0P6IjQshLjSywuN++4c5siR2/cNo4jzHTXbYDVxN7vclXBk9
vRjEburtAmm3W7GhOEUTVvTzrVUWz/sdTfk2UnKewjINlIt5N2PTZtMnrqFkh15SwxbEEoI1Xv2j
/94tMzAiW81RLFwIXVV77uC6ML97cwDKvZnJB5LEmRqVlxMMHofrJBi1hnfD686UHTAIbEcGkTGr
R+pqOYzx21P90h44ys2sy84ya387SXwwB7UYI1M2AxifCdv5jEMzAQEajKx/LOXAvsvdy2YJQDVL
Bgbqn/KCQe33as+ljMnTbSdaatTcXa8fzsdCgHupxtrJvk2jkTBC21nwgb8pyZb++hw01eWS4goo
wPK1mdceys/S1sGy/rXUhgHWV3BxzzkKu8kqkMqhRPrfGYmvhF1MPgdll0+KNc/TnQxDc7dRH81K
nZEzF462W31nnmw1YycvMZWPJBCYHl9MubM1WyvFt2uocIEhV5PDAU4H3QoqHEyTxARhb6Dg6a9U
AaS24rPNBND5aaLC/prG0yNbx1Utl1IR01VDH0hVc1s+1nxdZbW00ApjJH0hB5rs1OsJakvpBvcx
F/NlOeNdxuF6yFa4w94nZja8W4oNqqjEC5SfF3hmSIwOhkGqPTPi7XFbKetjYyn9W3MUytNsRfbe
nwdUYCxXEntLp53TY0qjZ92aU0FfJJtVYsLzcgjmlrkipokA/PPks48G5sz8E0epYAHIn55DCv16
ATXeWzrw5xybKmirhPnKg3P5d2LSpyX75or2eCGD31Lu9SSrlZ36vwMwrxv2xeeMQaVOcP5oJzJf
KwAsFtmuU9na1B1HNYeEehmaKnHAdGy7pTygeBXZcuElpyqXax+17LmW1cn9MM9cysj1+peUXMk1
ROgq2qucmrdsiuhwwe6oMNP4U+U4H3XiRQfFZN2ZHmOgJur9lMB4btGvAwzd9aGH8oSjOus0tSYm
O19VeQyRu4ujWPq8F1NKO7UFPhXlCU8h3m8zsl54PwPaDct4MY8NwtfTPAvYTsu3DcwA+aQValZv
SZnCmJONTuzSzFfFnIK80HyawWfyZKtA38nOKhXJJorTjnSBoGTydOJn6t1tqHsPsGFrugX0rUbI
H+f19xN+HNMTMkyu/zPgv0FKdEi7H8jgVhOvpTSat4PiDjDIEImGi8V2dEM4rlJRVyAwbSDBHula
2roaFapbshIlIuLmErvyZopFR7UQfcSfarHp7UwNI2Cx6bjQuC60TLs5Tvu0i3XnXgrRkdCCorkK
qT/Nums9zdZvQanxMELZmV00ftqJvc+DeYphOAfYq+avpW0fpwjWKV7e+Q6ScmsOaIznOojYrdp5
DeePOYAspm1C59DA9/yGncBy6qGbRNKLvTvCSCxcD1aLnJ2h8t6HRULWBFsVi4ibs/Zwy58S/jtq
Vy7N9vJ7/pxXyaqz9oHYm068BGn6GcnqUQfRoc8//FcqE8d+MlGMLWeJPusRWNL6sxDVpJjbfpsV
HQMvVnUVnRekjZs1825qAgxzs9Qu8YfHZou7nmYmokrNQscwi4oyXiwiNxCFvbTeXFFA7/VoPkiW
TX/CHF1F8+GYVZzFWEre3wC0CzAXVneT/kYF+Ag+qLiUtRqFm0sRHyZgPtlgHjEHdQMq16ZA98k8
pb5mjugrKRsixcpOy/1TCv+L+Y5U1DZMXtoxL63KelEEZD8SYJF1I93WKyKO+EcTdt0cfCthpq2I
ZRZUvQkK9NSzpf9hqi7XTJlIskQ8uJHB12u/2ZmaMpyEqS9jianhSulnNWuhVkS7wOl8qIQeyogo
D9uE+QlonWljNv719osZc7ByMlstp6F7NUc/htN4giGck5+9NkeCKPm8xj0xXzdpIlTdBMtaBrAR
LuwmpvocO18lY7fWEweQS0QWneTPTOrmWwveCiytI3M6TKIAp5LY9+ZjRRw8nJ8lvP0lAdEQKVW7
1EZ61wNwmz19quSAHKV77JkSrQuk7omUv9fT55qUkFWwTV+2LFFMrLuj4Jih+eUQJdKrD4BsL1Wb
7R7PhyzlX6QPPJdSKKWXozF86qiPFpwlLFPBnWfKQ+S9W8F6Nhh7ZfcLmC9fGdCP9+zYBomJ7+FD
85W4eihivNTHhvI7oOAI7aDj7UNcRWUNETNMU34HhnlqHDuqxW2vzHp/dWosX6Ikp8lsTZNrfClV
ZDes3ibiZmsyA3S74XXLaDb4ZxBTSbc/VzT5bBrDWWrLAXs39WdSGin34SUz8+ydaeAXE2bN/Yv0
wdNKdFeBaQRjvoDkHtQRVwsAh+hYv0JVePRfzfMsqa2n9ZypzvoA43ZmhwPUH1Omropb07e6Z+eI
AX0PKVEp3DkvzJI6nJLTWZivU84Bqj5p90EQYm3pULw+hm5rniTbyezPUQM27ek0YMPJR2T5mpox
Ls+HJfQ30xn2R9l4AOtdGzrSGm0vti9qxhYD7V0iwxvydFA+9m8WtHiN2maMVibnPsXUlWPbTFRh
G86p8N2qbqQ3vQxKO8IEbk6p8+RPhXN46qKlqdB4vIRiM/6jHPYsr1kFTF/fTXGMjnmqZvYEiXVN
dEFQnwYG3t2HSZj7Q5tVrwm2UjlMUzxuymMKCoIY8OoUgZcBfj/c00y9eyUgcNKsyGQd5+L6H4rc
rFNRzVMBHkXQRqvafQLD2tktjFW935JDWtr0ZF5AsPlHqIPPpiBYjP6UHwRn53T9fYLIt1OOjnN5
zSAV5hcA0k1kwrZiqoToF3kiONIpepbTGqSvJ2ubXc+JwPeS+XY/0D5eUonS/HceABHoArW55oH1
mfHT33YMXmewy3UpqI8Do8OLfTwQdzu9QEagY74+bP4ukar4RR0+9Vqgb4AXrx6wlxzD6upVNMRu
ImylVqrp/FAKzHhQ4CZ4EaciWmujCd/fb0XymkhTrWb7RoJbP7zhAqxuA4W4QtXeTjPrHaZIEu7h
yz8ANutVELb328Vx/u4VMpS14qt+cP1+9O406bBj8L43U7ULs8vzxFCW8ucdCi+7zMOieGGjs3Ru
tCIXT58Z9y3Uxhm5UWIM9q1Uws/IV2esXZ0A5r5is0phj7YWT8rVqo5sAVZziHgB7JMJMh7cBQmh
T0iNVen9iM9+lBC6Qryk4j1el8McZ2+kDdTYWiKcA0WdFgObJRfLElB9d15fyMdo4lqO9KzKICdN
uQb0LNDLtJDDCscy4jBG3qMEHW6rqmgUexl2F/OoErcmNYYuMY+rt1qpOXj4oeGsMPtMQmpNXtX7
xXUeoEXWVGIIFFDm9wDJGzjwGRHIjtAG+9ARl+hyOBB2KtcPkMt1nPwYHCZLDT6Wz4QCWq7vdwDO
ntcuzXmW/lsJJy8hnY3kZR22xnPpIf+3R8A5JMo7qlC4MS2VELkEr87HDdXewgzcnzSKwxpUh/31
1cAqeSuu+LB79nl9c35LVX034WR+MfvqEDfpyzPonPwls8K1vNdJ5d5OlW3f7f6Pc4/AaxNnOFui
keZ8i8oxX5twSKaxeOpyLpXRAeosLnum6AmaP06A8rwO0ErMUfPsul+D8J5SlI7TMVmEnJMRKvKW
jP+lfKzZ5Xw6pr3CeArjmRSOYbLbY1CUtTmJXsjoj8oaJdK1XTUSrcNHQ5dQkV9DUyW76POtR8Jg
+o6OSpyn5AXPbtKXK2TGXNPzGc805WmcOJqFDc3lmJJmd/zzlK13U0Ppukfsmv1le8AyWT1SN43e
ynYEbe9NbE26HvWDfPKgdLRjds0EjfYUktFNMfEg1hNJN2dTJKCn8IrFM0CdmPHhMI38GD+PpXR5
0K4mrqnX9Jqhh08nsHSlmapXkE8U/TFne4zmLhiseAZ3oVrguaqRp0i7V0f6op2G9yREslEf2sAZ
g14S/VvyzBKiE2En5partWXyjrGk4wL6D0quEadT8K0bjawvnGHi2XVpW/ARltxZgrzLkiuecVx2
YLGdNyecCQdZO/VfK8W8jbgB57Qdq1kfTNM3t7RiXake//VtUuoZVqgjPYPCnBUztYN/06UMeCJ/
coiS6N1az/+c8LKVRvDy4sXn6j2OZZf2ig8GE9biqoztfhlNm83QJ/O9+saRC2JTb/ZKmftTs+xE
UZyYC8m7KwGnr+T1unxW4MQWcJkA4qIegHVytPYCOxebayXqRSc5mq6S43P5WqbV+jK1dI+no1SJ
NrvhMXYqjwG1qcZ/mwStmBNooJeq3H26w6k/SRBtQDeI4h3cX+Q1JJIYChkeRFZOsJY2PL+4+cl8
liaM8Zi4ymJZyC+74Z/GOsvU0E+5teEbq57nYnzRoDnWAPLu+aqkVTrQYjSJ6O9M+XmGUbwMOnuG
xeI9r/3NALFzQh+h1DN3LryuFcQbnmGNvrNKB85Ozy/wBUbrAM3D+e6xEa7GujCOwv5dwoNfeQ2m
M47XCe1LNLewrm8O9gLB3WnPf0hTcATbcj7GOLua0LSWBTMdn1aurRoXpIlrVblj+JyXmQer++0M
y1kfGsVj5VxAeEixPCXIG80m/dFIv3H1atpFkxjkezl0YecDqp/sCs9tdEy10q9Y+tXljPpzCcaP
klB3EivzcwSeQzke6m1K7h+otj4wyNP5/AWzadBIT02wl/TByLpKLOvlO/NkDwm/8bMv7KZ56iYr
sVF21PG3ID+b15qwdJg0zKQdcdIX0XyYHsaL8+16auBe78RjaEcdbgcfi5UC58UnR0/ha+wGp3JB
xjkNx4bE3Hwlmb6a1HsJYpAmUqJSM22kC+fxXXZgjlcnFhk6gTc7ARuxCyxQTMM4LsBHeWkV60UX
2k8Y762qXyh1m4kdNB26dNwHVFD2NtYjxBbbFOu2YTZwvDvPpHjcF8UsUJkPFxV9OoH1eWdTjY6X
EK6UQbwuryhRTDtWtwwtd1N9sDAV2DRTaKlE5ZRy4LQ0hJ6IEicaUJ+ZajEeBI6VsgUH1ZSYnyao
Ssf4Coa7U/4ux1d3zM4n5ZcPWzB+kWccG+Fwe9gjKPOlYYBa66/mJSCg+zSCq3Aov4LXlnYocTvU
Ib2Z0lTK+UEn3Cr2rvybdDtmnCEQjU+STWQMX8mxzr5cWHso6ctUJKZ8w65jvFWKKc5UUabbx6AR
g8aAmAeb+BjZVWJuI/6dyjmPsvXNLzb5QELbt8CuO86f5vuUE25LQC7Gv5qla8uka/afXrR6P3Fy
hY+VPjtfXcWrph03v17wuoaSGKhi9UKJF26sX16pfAfJGh4mU9QnJBCuyXtTooz67CYhH/+LjI81
RLnRH6RA2PK6LsfLNvaXEd2KJ78MwjOW6n1pqBviWCrIymWy3+4RS1T/XnbrIP19JM20PWP5MrVV
JT06IDv25TwciuuZYkhVcb9Poe+OxbdUTgtjMRvcCCJCXyoJ+3o+KWrmEynqw9n3WKR+APxqWRsi
nHvG5mgXspvL02p0loOB/vKpu5CUP+eRJkuzVHdtRZQVrNTYt1UpnPcw7aPqwNz4lBH68XIuFeq3
6ziOtfqARsPdZiy5xUBqfy+mUvgEYbgz3yBI/jOTuD/Po0pqSS6Jprqh0LUXAo9l1xOIlD2IKeo0
6vDsNipNAsBsvekiMJeXYBzvzHEQrqBNSdePSkeqxHKzaZV94LWCdWcamypI4pGUtypxU3d1DH73
pJoktFwFn073iovTDbxw/3mwUwKNLGD5ukzdsveyWg23a7o8v7EtABpDLC5RXwNifCYvDlOSVk+3
ZAp395ad4fO8zOnW0t1yN4/kMxD52fD0JrnzVV9XqAA/C+a4vgYf0S6MFpvO1tYSVg+aRcgmiDtS
NG0T5qFdR9nxLFkqT3EfQckuu+2LJeqn9PUObbTjkRRVU2gR+nMO3nVoS1qjQ5rmbN5PgM14U2i8
6GUcVeFPfwYUliG7ds42GXYrJj1bmyNUhAv7U2mCR7FqbrB60IrGYZn2hytf5lMT6A7i52WZ3uEc
tTdDSclWsW0r4zrCTtzPJor8vTmeWUy0eLmTOSSdsDY8kGeTmU4LWwXmOep63vO3+JxL4A0vn1JZ
QYzHUh6bVPPm8LaK53J4ZDbOoxlr0l7Woi8kaM3qQPPUiHuw5h4HLTPVbKabpFkC7C5P7sVSN9nm
lX9hxgNUyHazBcYzQVqfFrfFJfPDdqXyJ8x5Jcs221CGwYz4JCgZHwbxRROS9di0OFhT/GK+SQcr
XubqZGaXZo7K7rpguMNx5M/lKcvuxWEXFwDOGykrvv7P9OXUnZUylIRl7O6/0+Ypl1zg+csE/6JS
2MG0ZwVnGvGzrzsjwG7KzmaD1noQ+EoOPUK1Ay/VD9PVHKYrHg7AOCr+DWJlSLoaKuknHCkvnQ1i
iSWe83gtTzMxMOXNVauyFjC+j9y0gJC6SA57wiEu1IOUzFHKc7hwcw7WOxaGiq3ca/ZRXuIV/dXM
bJqiVqt6OCbsceGl/pwQJsk6WOjTvbSan5N5R5rGPHkJ/1X0qq+lGH8S3FwmQ3eVgH2FzI+rYZK4
ulqN16v5dzTM2RhKK3ZP32yTLXcbMfYFa5hwT5W2jbfpajXUwDIAxvlAfnbubPECT8Vrl6T5Kd63
vsl9sXyxTQzoouwtehsJ7TjVPRCkhfQ8XTWJeUDDuEHMkPNlOOQvZZkJc+C4u9jrKfh3tyIxgjWf
P6QdzM3vTTG9lhFMl8UYtTsuyhIa4hFZl5zfnr9MvWxH50tNmsvbdbmJ893LdNwzwHq7VP4stDFG
Y+su8rEgeue9Of3pFa6W8OFQiO8d+Wf4YQRvDuv0qRsJvHV2kMrVLqBJKhevrPEEHmUkz8fXT6di
Gqji+WMqyb36y03igrBGlqVcrcoCQDWa+DiyV4ocNsjYHVK3050ex8piTqrXxmbZxHcy7NvjGx/P
i0cj6iyYVYW9vGFkz4d87NONrG9TAJUQeF902FifKSW35WsGBlNAtov1MARvPr05/wZLJRO9DGoq
Xi9ozZU9+hDH6E6gBirLBv1u9nVaHvpgtkwY147x5l63q6OjLt7YPAyrtRwEt+GIc+TenfOxTGIS
3sGf3CN7bXVbyfq5N86mMXkoDzJ96LP5UZDgB8Ect6QWGx6MsbsbI3YOYO3NJ/y6HupZF+8R0RS8
puQQLEGw70wDmaEe+rM5PFiKqFdsXZXjpAl3pDJZLZvYU6yV3avrQM6jvdyDLJXS3CzFVK4Fwy62
7yaAXy6BfyEleGPWTKn/nU8VpOVx3Nps0WBJmMUOLDE2SkNg9uNyudOJld9zBsuIdg8GMwxxHao6
fYMjThH38pgOuaZ3A5LRsFc3liTqIL6Rl5w/d6FuU/g8d2uYbdYOldxomWFvvicN+xh9hn1DgwI6
DNnw3tfh57PLmewCytRytIa6rZcult/xYQd4hTTmGI3p8/HvC5D9Yym2hspm1pdN/F4fNiSzq+82
iAzc3VxGD9ea0jHl29W2Uq3WhUrFZxjt2F8J3HSs3lbJ4wt837GaKwx7Bq9QNsdVQ11yL17CPG7g
9UuE4YCkarpIplIFZrKfxrCnwtQOtonlLwnHg8M+tVoH8juvJmYdjrD+zbx8whblZaDYNbv62xDu
o61zhGzvzsvhNnkD1QibMidzscumMBHkjqTKf5+AuYPo/Csoa1D02qsEi5eru9ReBwGTQqNK3DxV
S9B6aYeeWitKoZu2TASd3RXG+4Dpq5SOWzwr6FN5vcjZ/Zzxrcnu12b88dEus1kDsK515bWx5cZl
Nl6MRQexUHbqdhHjtS0/T7SvzmsJp+faXMO3/0jWfH7AzZeXT0qZ+Ks5xqH/UhzGMg2tj5DyFshy
xJ9NRzCS50soqrLlaWXGfvkQoZiqjmed8O2AnKOHtcnxqoSXLEdT1PtlD6rltYrruw+x7wMEwcHb
AsFYYK1uPVm1WoOrb8wuIJbjWYfYzZU98GidoZ3gzzWxUrTk/Hg1aqEiap6xYi3n13o+YMX4TDrk
Hm23XGwXekN2YzU67BGXix6/lLBuVXsgFVNHabjVpYvEqAdtzlfBf+UlVwWnZ9uwKGDZtJMZkl9r
3FoKHx/BY6YfRN2vwsTXU4J7Ql95mGmSgSZFw47agV4iDzVRbaOb2trQhKa7/XKXt5JVJgfdED+q
xum8du5mry8+aTWLBp/mtU8/z8CG7FRleOT35zMXGXAmDDxevJhXX1clxCTlobSQNpnQx4mZRoip
rN81cgauexZjxetmnlUZfdJT7OCI6V5s3L9H1RJXejmY7ouZGaZsG2emsofjDztMQ2YwAu/DbBBt
9pEJ6lm8kUZEUDyZVSCZG6kdb5qlJs+YPCNJyW6WHISar8AUfIHscM5JrjXzJDwdAozty58l0lFg
coM2RVkbq+7l/QkKo1Rc2d0/708ZfBP4el5epPoaX27IafmxFO8pEGWdegwT3GR48TpycQVLmv+Z
R1OHdp9ToZEH+cYKGax70ycMWmNwjYyFHZXN0yYQVBFOCT+WmOrsATzKmdM6IT/RdYDzMF5Lmw8s
vIuqsEiIet7ZYOIX9JXnCLurrvjsj2NhPGsRPwQj3aQU8Z6LzaIew3Yu+ZoHS3BqHtjcksrO3US8
TmRUqGDR5NN5cpGqkuycNSzQWhmcTHGv4ySL26mRCqvFdTTI2xXGZHcY8atUu2/G2NqxZRdg1QGZ
7Jk7zssYGpR+ooviIxdmi5EdtqwLc2U3co3L6rBUkWgS7sYIhL3CyXgu2zcGnMOImT7N/J0ZXHwU
zREY9kI4rNIzMceHWiymUgcC8F/lMaBEXslHryotVY3Ydx9WJjnpRIGm1Qr4I+tRvMJu/TsoD9XM
IrqtWRfXbXW5Og6LpknlVP5AgeWo+b0gN94LO1Gjr1KQPpAfRyV/BzMpweK+DlbsANwbLeADk4rP
aoN4NhG/wZTi5fQxpriVmtblbK5Rs1Qpa7AdajZazgmxBsmr4K6A07fwfDkhpTc7yK4PG0W8S0I7
qseu0pVxVr6oSvlqxPf0ueQs8nlNd1K8OAh8mF1b0ZefIeqtsquQxaJXsu5n4bd3GaGYLNVgJ8N2
dmX2tFMvuafTBMmqFG52rzp5j78pnCRAvfJ27j1E9t9SlAfxlSXg7LE8f0SpTWw/hPCn8y2Qd2tc
/l9TsDw195OjfeHWq4BxkVrZMtlFk2s6i1GQDI/Lr9g6oQE8S1WkFarQD+JZjjLYsKjbgWEeyqPI
K66JFoA/lY/Dt4k2Skmzk2wNcqQjVXumzvnsuQHmm0Kkf5BibpCVSRcN9uvzyhMjbYDlszD9MsF8
CCwVr5Rfq1m9Sl699y5+uFJXluxeTom6ijEvwnFYv5fJFwyBkCT02MN0FxeNzD1pLFNU2j4FvE55
8HWQJkjWzrPbhoCRUzgUh3FCFXtNAmD/sAwkNGUPzPL61wj0xy6geCf2OdF/sU013/6MkVbTwlTA
TmaajE9Gq7W4kN0ZJ1fqQx0Rh3uhZBJa90bKoSvvs4RsofTgt/nbAoWFyecM9iuLVfm9xQdZb7id
md/JeLjZVHHZRxvbORMfgGoum81Xzuo9L6m4RMvDcEY6TTL1RILyGWacXa7lTaMko3toCF1BXo40
5Y8idk8CoCPFO0rUgJss3EX/Yx6o7JlbGo95ezFtwH3peDWU/3QWp5/LQ0sAl/OZgzRUr6TJFeTk
spMWo6XqJQhGV1TaFz99IOVotbRmA5O1+HVkWH0kPs2g+LAq8+WE83g3xFbZiA5sc0WfgC49y8NQ
r3vqzeo/GqWivwauV7HsZUD7VPDXOdJBLEE7GoGh8QJDCK74oNGnE5Z/k8dcuuH27G1GVSaV3Y7A
dtKUDmSLJpes036LXKbH1OgLKyksh7iVzLCv8LJqXKHS6OvbxdrLGzycT4/ywwSJV6z8E0Ts3bHJ
dWxpKbz6aP2Z2UlZp1Mq7HtT5iaTsuLDVs/IfLZlUcNC2EtZ88c9R4/S+WwUSBeA+XTrn9C4Dvr1
JnPi3yWoOSuzJQXVdJpNBKk1PDZIXtCE2BJSGqSPeZG4m7zRxjAWpm6r2vZS3w6qu3jp2llx5Itg
wE72GY62WAgZQajvTGErXob8dsKxzxFcJZguQ0rMINajzlTzADg0PrrmVNjG2sat+Selsw74bjJk
v3IdWLo6gcX94AREwxC/IEga8Nn9GN7FHiZ1L9l5I73mXJp006uZdvueqKtkH6Bwt9KC+g/xPvmw
FVp4O81mIybD61sl8akd6kxWIGtfyyOqiP0qh70aVQ+Yu23DLhZYel7yNLNxSlB2euMpBm0BqkEF
1jGaTpjyWerxDYb70/5XwyimBAOgLxUzzI+S2oc8tlHH9GPKJgZYBeZCfz7+sO2aqHZnv4rtzZRf
g+EUlvvvUtl42B5R9/xSQns3y6vLfg3IsBHapUblyniSjeG9RFy3Kf3fINtfSPj5WqqYffQ6p9Rt
xvHJa9WIgE6oGPdQbC/mQxIrP5Z/V2P31+aLDZZkj22CREejFhbTJolx8SKsXarN3/DJu0GQ2cpd
tas73ve+SiV9XAbw4fS1Mkqol0D7I3a6mnDaYZvhbDJHh+HZbQQUbI/szHbx3uboBbFanwA2dpkf
ymOJGe9Jh+LPc7tZfLwMuOUScRCQXUPRnly4eprR8xm05tmK6h5hwW18CWbTaBkryuMJsvkTa27K
h6LA9/BjMucrEuuJ+BeY3wiU/j8SluwLdgqC9+c4khJ7RWbDJQ+8+wn43K9EmQCzc0DWz2OkN5VH
9rRpJcCV7rN5szB4H+Tzj+ZDUD1u4ATVINZzeEiJZMmK+gpzqeGvG/ICYjcbICSr2ct8sIvwcQzb
lB7BHJaEAeIkT2xpGC8Or+H4zl+5nOppgf3q/ADqV15K37940Wxt5mqlujapejHwcoXVVs5W9PG8
nsJIclorkNweNz4ESF7KY0YbZ1pajwloEfYDjINq3tpTqLtY7POEv0Uwp4ulf5IHF7vYQ5KAI6Lf
Ntu/lrA8EEm9GUCaYX0e3Esf/5UgHm9h8ewfzSMGXRoOHs1yKDldNKxROnc1cttt8LKLpTunQ4cw
UI6FqyykdXZMfvts8dGHmtsP0+4fSdCaxKkRZ+k0a7heIbEbM6H5/eJdXDw1hMLJHj7hL3cHjO9L
Ge4XT/Gq/A7lF6lMy27gUO9dpuGOQFMsAhcUSnd22SMYt0BvE+DCB9PBbyAKL+cTUYg8UHcZxQfc
ZQ8e2UC4lhLm50ndEn3/rfR3T8jxDDS1Td7JXF6P6H09z5j2YXPXxScHrYrfT0fz8mwD+5sfWqub
2MuioQ35XoHFRdtZrq+jvu2ytsye54ofG/xl0g+fZ1gpz/SeNL4SxteFkntX+upGydLbqQJ+T64f
SwddJONrrTqHR5uhVrYdKwpmX/cgZkI3fYNYs1vMMeOF0a3zte7b0lwfyaEuMsoefum1loUI1Bk1
lP5Oedgg5/RknjiZJFPzRqrIhuc3KUnx4gz/ZcYZgHIPRbdTkyFS5oYhRWkv64ZP5xMQ8YwVuYwN
kxXclqGrPrQ6rIIAbyWePaWjvVVuHTjDdSVQ4oFBpIaHB8sO3pyHVIL6cPyVrRnMl5PnwiVQ7pQ1
KdPxRHQ3JLQPvnQjEY/rJB7p2ylx2XNav5+KysQ7IbtwUArpGPTUPrfm/y8Em5RtMIT1tDdLxbdx
JIPCij5EqXo2JahZZW2fNypfno3LMIv1XxPzPgwPpQsSwxwp1HLE3ySyQ5CZfon7t8JZAiw09uyu
qr+Q++OI62sEqwtTO0Q6D6p6fpqQW6pQVkKZt6XQPJoA34L2vo3owY3CRxlu8bbX2/NBaMSbfFnx
C1SI4eU+62PMoI2AOkuz7oR1stotV0N+MZ8lvHieIdhJ/DwvCWhpCxzZpDI0liZmLCftWiafNV+H
L1eeze72T2f1ycdTWS0LU8OYEFDDcSJNZ8j+wpH9Q0K5I+GGdSzxb2TGnv0KnEPxOf9Tc9c6grEW
L2yayCHcOt2cErImSwgZ81GNrtfBRsuwUM5tDYvQtSJdoy57Gvc+NccOuQvaRHMq9+V2RsfI22S+
Xk5l2hGW4UwMDGt3lRy5LUo3UDhexe+ZHBYB20hxhybzzYTg54TDTcQI+aVa1fkEyvYoDWDxZtNO
KOsKac9c9OS4mHKfkuKWfUl8phWJ/mRK2RImNV4J2sY6gaXNndam0F1uwT1fA1YiPQxRI3P41klO
vpsGMDU/i3tAs083hwtAAzAW5o1zlG+/ME+lwBVGorV0R7twfRX9+HkItkbW1RL45fwjVIIJ+R8T
bH/HMO9npgNEJEuRco+sg2jlPESzLsxjBw+nUuoq4/e1fHehTn3FW8B5u7Th8bSTlZDNXj+Uz2uG
FscKwj5V1OplPfOkp3VM/86xCHuy2NoLbdzdwnrUcvFV5KbN0MUuCiGuyQ0IMwV2m859LDt6pgbP
Wj59UhHPLk8wkcVHGZSSmkmAa5JqcK0q9gSoPCVec+ti9RhASC7zE1urGfRA/EUxxj6/6O98GPTa
VN1NruoUFQPATHglXeE1qdD8I1uZvQBUv5dmXo66L2bGnOzBPP76YiKB0Cimd15miuxcxzy2QC1y
PwV9PuPzXs3Q/oiH6CppEeaGBQzRa3H3A/f4yFwj+8pQKRFbqAT9MUXYY0iXJxKWwTriwdCLNDql
E1i3nC7BdnmOpeUYFvqr4jyXjzOvF9OIbHONSjtpTg/T7JaH9WEMR36AhHqaB/F1ltj5gprpxGfa
2rJwcm+KVzN0vVyg6ywTIhejevA6tg2Vv/kWHzQJm5RGY5RKi0+JY49GvYv2t6kwTshJtMKbLxRl
XUc1naUwH0iB+zPVsArttwKXiF4OIbr3pY0hf+7iDBTqw3+TQjGrV1WNmZfzhEiBPHZ7ZwfPa4Ht
lYW9QLCWgtlLkFYK947dccWkQoN2NJ23HRzwD2ncLxHjLbQdTpqByVOf1KBl14eWyEY3Mw973xUi
ilLczm0kxq5tOerkk0ILsi5Nky2hcNvSMX2TYC7STgcjxBav4uLzrtAQFmTWTHVaJR7L7pccYcyr
eTtMSG4D7TWyF+5CvGJZp3+zVLJedfpGfkSItaPUIPULfPxyfbi0eDtK8YltoZsa0QuEltsdRBlT
5TDK5Z0GiQcGxTO3CPYBuW9fl/WlPD9cBXEuX9zx8OPtrE/w4oCmAOaVpHil59UJcm0Jihd/h4op
vpFg+WgeJ/UV8UxLugZROmayumjg4Tc/nkZisjwFamZJWVzvJoq54NhswjwluPOV28HyD9emwrCP
2kiraGwWr453O8MisGJhi3VHvl0QXa6OsIY9GXk2azYs9jY2uC2zC04AyYL8bONfU+XcmE8NuNZy
eNd2FvzR8SQYEnCu+DAXtScuiP7FS/qyW1z4Xk99+Pm40Z12Z3briuvFTIq3GrQhzIc5X7flkqfr
WmG6U+e2atvZp/vQAWIAn7J6MB8sPcYaCbNXDT+SEOd0b5OrXxlm0c6bt7rEy9oEkpFQtRWsrSrn
jKzQ11JylwmVbWhod4qjTdVjw/BwJD6bOrSToTMyuiuvywBm10se7Rzvf/k8yLuWipgmJj2Hg+qv
MG0T7NfiWLNHcT6SFwk04tm/+DdBZtXBVWl+s9njegrU/HKxBY+99b+Q/7/4WFOyotnmV6k8RrPm
bbDelB86u+qVwo7aZvycCf3wbbZ6k8QF8X8a0ob+xYRtLfKqxC65MZ7oo0iNFnunK1OhF9ekwzXq
klNZR+T/nDdf5FzJWshMFfpdKUNH8DoW0Wps6Qo4mf8hgBLaSYI8InssTfZ/wVFuXFOv5vDP/ycL
c+JJ5uzfyrBU8LmSNcYrwh5ju3r1fUOb1ze25v/ueKy56fi+5uNN1RMP7N3X3NB0uuxgdX11U+2+
3dnfu/P/zWNZY5vy/+k7dQ0Nh48f3X2wrqFqb11ZY9vKDstq62ubq5fVVtftbyy9bn1jO3V2ra9v
bJ/toqm2/uCxibX1zdUHq5vKjuw9XL07/6OxrLLlrMn6SofKlmdmNXa89AtHG+pO1zccqd1bd8nL
+D+uPMU+quuqj1TXN5c1dvr/fyu+t3tfQz2zaWgqq0jvrddbZY2dy2valNe0q2lfXlNW2WKqRtSl
ssWp6xq7rqlsfaRhf31jt8qWZ8/VdInvTtG73d/V3NjjXHNjz/WNvfTBNTcqyr13Nvb5mykfcFx2
/8384/85s2y1/mvsm++rX37I/jW9bljfOKDG78SoDKxh06CaAf43yP8GVN944w3Xr28cXNn2YO2J
vU0NjUMqB58dc7Sp+kDtqTFzho45M2b80DFN1Ueb4h867phz+RGGhnYa+LBzjcPLK9vyhcYRlS3O
VLaOH28cWdlKH28cdby5cfT6xjGS4qs1r/KJ/wedQ2+g
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment