ラック・セキュリティごった煮ブログ

セキュリティエンジニアがエンジニアの方に向けて、 セキュリティやIT技術に関する情報を発信していくアカウントです。

株式会社ラックのセキュリティエンジニアが、 エンジニアの方向けにセキュリティやIT技術に関する情報を発信するブログです。(編集:株式会社ラック・デジタルペンテスト部)
/ セキュリティブログ / セキュリティエンジニア /
当ウェブサイトをご利用の際には、こちらの「サイトのご利用条件」をご確認ください。

デジタルペンテスト部提供サービス:
ペネトレーションテスト
セキュリティ診断

Crypto CTF 2025 Writeup

診断統括部の中嶋です。 2025年7月12日(土)の06:00(UTC)から2025年7月13日(日)の06:00(UTC)にかけて開催されたCrypto CTF 2025に参加しました。 Crypto CTFはその名の通り暗号(Crypto)に特化したCTFで、全ての問題が暗号に関する内容になっています。 私はparabola0149として参加し、結果は28問中15問解いて19位でした。

前回のCrypto CTFのWriteupでは執筆に時間がかかったので今回は開催時間中に解いた問題に絞って解説したのですが、結局2026年度になってからの公開になってしまいました。 Crypto CTF 2026が2026年6月13日(土)の14:00(UTC)から2026年6月14日(日)の14:00(UTC)に開催されるので、その予習にでも活用してもらえればと思います。

また、このWriteupを執筆した時点ではブログ中の数式の表示が崩れてしまう現象が発生することがあるみたいです。 ページの再読み込みで直るみたいなので、数式が正しく表示されない場合は一度再読み込みを試してもらえればと思います*1

このWriteupで解説する問題の一覧

Crypto CTF 2025の問題は6つの難易度に分かれているのですが、その名前が独特で難易度順に以下のような名前になっています。 今回、難易度の高い問題は解けなかったので、このWriteupに関係するのはTough Cookieの難易度までです。

  • Warm-up
  • Easy-Peasy
  • Getting There
  • Tough Cookie
  • Brain Buster
  • Head-Scratcher

このWriteupで解説する問題の一覧は以下の通りですが、問題名だけではどのような問題か分からないので問題や解法に関連するキーワードも一緒に記載しています。

  • Warm-up

  • Easy-Peasy

    • Interpol 多項式、ラグランジュ補間
    • Mechanic ML-KEM-1024、例外
    • Vinad XOR、RSA暗号
  • Getting There

  • Tough Cookie

難易度Warm-upの問題についてのWriteup

[Warm-up] Welcome! (361 solves)

We just learned Base64, so we hid half the flag with it. Decoding is optional... if you like flags! CCTF{w3lc0m3_T0_7h3_m4dh0u5e_aDR2M180X1M0bjE3eV81QW5kdzFjaCF9

問題の概要

この問題ではファイルが配布されておらず、問題を解くために必要な情報が問題文に直接記載されています。

解法

Welcome問なので問題文にフラグが記載されているかと思いきや、一部がBase64で符号化されています。 その部分を復号するとフラグを取得することができます。

#!/usr/bin/env python3

import base64


data_1 = 'CCTF{w3lc0m3_T0_7h3_m4dh0u5e_'
data_2 = 'aDR2M180X1M0bjE3eV81QW5kdzFjaCF9'

flag = data_1 + base64.b64decode(data_2).decode()
print(flag)
CCTF{w3lc0m3_T0_7h3_m4dh0u5e_h4v3_4_S4n17y_5Andw1ch!}

難易度Easy-Peasyの問題についてのWriteup

[Easy-Peasy] Interpol (129 solves)

Only brute force won't crack Interpol! Its massive polynomial guards the flag fiercely.

問題の概要

この問題では以下のファイルが配布されています。

  • 暗号化に使用したSageMathファイル (interpol.sage)
  • 暗号化した出力結果が記載されたバイナリファイル (output.raw)

この問題では最初にrandpos関数で点が生成されます。 randpos関数では0または1の乱数が生成され、0の場合は x 座標が0以上の整数であるランダムな点、1の場合は x 座標が負の整数であり y 座標にフラグの文字の情報を含む点が生成されます。 フラグの長さを l 、フラグの n 番目の文字を数値に変換したものを a _ n とすると、フラグの文字の情報を含む点の座標は以下のように表されます。

  •  x 座標:  - \left( 1 + \left( \left( 19 n - 14 \right) \bmod l \right)  \right)
  •  y 座標:  a _ {\left( 63 n - 40 \right) \bmod l}

randpos関数により繰り返し点が生成されて、フラグの全ての文字に対して点が生成されると、全ての点を通る多項式 f \! \left( x \right) が計算されます。 計算された多項式はoutput.rawというファイルに保存されています。

  • interpol.sage
#!/usr/bin/env sage

from Crypto.Util.number import *
from flag import flag

def randpos(n):
    if randint(0, 1):
        return True, [(-(1 + (19*n - 14) % len(flag)), ord(flag[(63 * n - 40) % len(flag)]))]
    else:
        return False, [(randint(0, 313), (-1) ** randint(0, 1) * Rational(str(getPrime(32)) + '/' + str(getPrime(32))))]

c, n, DATA = 0, 0, []
while True:
    _b, _d = randpos(n)
    H = [d[0] for d in DATA]
    if _b:
        n += 1
        DATA += _d
    else:
        if _d[0][0] in H: continue
        else:
            DATA += _d
            c += 1
    if n >= len(flag): break

A = [DATA[_][0] for _ in range(len(DATA))]
poly = QQ['x'].lagrange_polynomial(DATA).dumps()
f = open('output.raw', 'wb')
f.write(poly)
f.close()

解法

生成された点の中には、 x 座標が負の整数であり y 座標にフラグの文字の情報を含む点があるので、適切な負の整数を x 座標として多項式に代入すればフラグの文字の情報が得られると考えられます。 フラグの文字の情報を含む点の x 座標は - \left( 1 + \left( \left( 19 n - 14 \right) \bmod l \right)  \right) と表されるので、 -l \le x \le -1 の範囲にあることが分かります。 フラグの長さ l  19 と互いに素であれば x 座標の重複が起こらないので、一旦その条件が成り立つと仮定して考えます*2。 フラグの文字の情報を含む点の y 座標は整数になっていますが、それ以外の点にはそのような条件がないので整数ではない可能性が高いと考えられます。 よって、 x の値を -1 から 1 ずつ減らしながら多項式に代入して、 y = f \! \left( x \right) が整数でない値になるまで繰り返せばフラグの長さ l が分かるのではないかと考えられます。

フラグの長さ l が分かれば、 x = - \left( 1 + \left( \left( 19 n - 14 \right) \bmod l \right)  \right) に対する y = f \! \left( x \right) がフラグの \left( 63 n - 40 \right) \bmod l 番目の文字になっているという関係からフラグを得ることができます。

#!/usr/bin/env sage

from pathlib import Path
import itertools


data = Path('output.raw').read_bytes()
f = loads(data)

point_list = {}
for x in itertools.count(-1, -1):
    y = f(x)
    if not y.is_integer():
        break
    point_list[x] = y

l = len(point_list)
flag = bytearray(l)
for n in range(l):
    flag[(63 * n - 40) % l] = point_list[-(1 + (19 * n - 14) % l)]
print(flag)
CCTF{7h3_!nTeRn4t10naL_Cr!Min41_pOlIc3_0r9An!Zati0n!}

[Easy-Peasy] Mechanic (109 solves)

Mechanic’s ‘post-quantum’ lock is so easy, even Schrödinger’s cat could crack it, alive and dead.

Note: Please re-download the file!

問題の概要

この問題では以下のファイルが配布されています。

  • 暗号化に使用したPythonファイル (mechanic.py)
  • 暗号化した出力結果が記載されたバイナリファイル (flag_22.enc)
  • 暗号化に使用した鍵が記載されたバイナリファイル (output.raw)

この問題では暗号化の処理にquantcryptというライブラリで定義されているMLKEM_1024KryptonKEMが使用されています。

この問題では以下の2つの処理のどちらかを選択して実行するということが40回繰り返されています。

  • 鍵が生成されて秘密鍵がoutput.rawに追記されます。生成された鍵を使ってデータが暗号化され、その結果を新しいデータとしています。
  • 秘密鍵と同じサイズのランダムなデータが生成されてoutput.rawに追記されます。

データの初期値をフラグとして暗号化を行なった結果がflag_22.encに格納されています。

  • mechanic.py
#!/usr/bin/env python3

from quantcrypt.kem import MLKEM_1024
from quantcrypt.cipher import KryptonKEM
from random import randint
from pathlib import *
from os import urandom
from flag import flag

kem = MLKEM_1024()
kry = KryptonKEM(MLKEM_1024)
pt = Path('/Mechanic/flag.png')
f = open('output.raw', 'wb')
m = randint(2 ** 39, 2 ** 40)
B, c = bin(m)[2:], 0
for b in B:
    if b == '1':
        pkey, skey = kem.keygen()
        ct = Path(f'/flag_{c}.enc')
        kry.encrypt(pkey, pt, ct)
        pt = ct
        c += 1
    else:
        pkey, skey = urandom(kem.param_sizes.pk_size), urandom(kem.param_sizes.sk_size)
    f.write(skey)
f.close()

解法

試しにoutput.rawに記載された秘密鍵で復号してみたところ、間違った鍵である場合はCipherVerifyError例外が発生しました。 よって、この問題はoutput.rawに記載された秘密鍵を逆順に使用して復号を試み、例外が発生したらスキップするという手順を繰り返せばフラグが得られます。

#!/usr/bin/env python3

from quantcrypt.kem import MLKEM_1024
from quantcrypt.cipher import KryptonKEM
import quantcrypt
from pathlib import Path


kem = MLKEM_1024()
kry = KryptonKEM(MLKEM_1024)

key_data = Path('output.raw').read_bytes()
key_list = [key_data[i:i + kem.param_sizes.sk_size] for i in range(0, len(key_data), kem.param_sizes.sk_size)]

ct_data = Path('flag_22.enc').read_bytes()
ct = Path('ct.dat')
pt = Path('pt.dat')
ct.write_bytes(ct_data)

for i in reversed(range(len(key_list))):
    skey = key_list[i]
    try:
        kry.decrypt_to_file(skey, ct, pt)
    except quantcrypt.internal.errors.CipherVerifyError:
        continue
    print(i)
    ct.unlink()
    pt.rename(ct)

ct.rename('flag.png')
  • flag.png

CCTF{k3y_3NcAp5uL4t!0n_M3cH4n1Sms!}

[Easy-Peasy] Vinad (211 solves)

Vinad's ‘random’ keys are as unpredictable as a cat. Poke its weak spots, steal the flag—chaos included!

問題の概要

この問題では以下のファイルが配布されています。

  • 暗号化に使用したPythonファイル (vinad.py)
  • 暗号化した出力結果が記載されたファイル (output.txt)

この問題では最初に512bitのランダムな整数が512個生成されてそれを R _ i としています。 また、それとは別に512bitのランダムな整数が生成されてそれを r としています。 vinad関数を使用してvinad(r, R)として計算される値を p 、512bitのランダムな素数を q としています。 vinad(x, R)関数では x \oplus R _ i parinad関数に入力した結果を i 番目のビットとした整数が返されます。( \oplus はXORを表しています) parinad関数では入力した整数を2進数で表したときの 1 のビットの数を 2 で割った余りが返されます。 また、 n = p q vinad(r + 0x10001, R)として計算される値を e としています。

平文を m としたときに以下のようにして暗号文 c が計算されています。

 \begin{align}
c &= \left( m + \sum R _ i \right)^ e \bmod n
\end{align}

出力結果には R _ i, n, c が記載されています。

  • vinad.py
#!/usr/bin/env python3

from Crypto.Util.number import *
from flag import flag

def parinad(n):
    return bin(n)[2:].count('1') % 2

def vinad(x, R):
    return int(''.join(str(parinad(x ^ r)) for r in R), 2)

def genkey(nbit):
    while True:
        R = [getRandomNBitInteger(nbit) for _ in range(nbit)]
        r = getRandomNBitInteger(nbit)
        p, q = vinad(r, R), getPrime(nbit)
        if isPrime(p):
            e = vinad(r + 0x10001, R)
            if GCD(e, (p - 1) * (q - 1)) == 1:
                return (e, R, p * q), (p, q)

def encrypt(message, pubkey):
    e, R, n = pubkey
    return pow(message + sum(R), e, n)

nbit = 512
pubkey, _ = genkey(nbit)
m = bytes_to_long(flag)
assert m < pubkey[2]
c = encrypt(m, pubkey)

print(f'R = {pubkey[1]}')
print(f'n = {pubkey[2]}')
print(f'c = {c}')
  • output.txt

長いテキストファイルなので非表示(表示する場合はクリック)

R = [9765507689557698353272499404376055006893114870722334943829066982323649854068670692016090678182002045854934465496255639568419408057967403077442935343626825, 11708898940537916806152001023915219039254376113964318646846468851082862998474307181449263359025364805731589596633658749151565367764957039398127836183355773, 12669179058860264531287509749033656639714912455141413836571455208331612009073261317846891011360139750565008606283828854617732022759044690597726610423842306, 8077978446545940752393539454138471756479629349687913903696824137482277851253389433983596973344259642939665632837117616919395672787907082418194190775089107, 8614110157141031165356634580939732362388616840839234150391192983993712015062756021521314005957472425836289494798892173997264892789412148966197694660703117, 11200422887640018916451068227417366461911524989297558606490635349305963739100610033950044371242333111323214224770762216521059100303944952985746475079748611, 13344967541918888350493621536064107613996935355929459462556969193217066151051813141305753196562646036951018522336875527234616765944842322571767325716825932, 11981765598933934215777031359217259391491032718492218537362638328430450533079579349217361987426931674053079751146155733914706189885662702132824987662710697, 8336735961875398528252663816688783160531281752736009834879166463079240506155985556972742196248747367208401431514654182921869396379563488799913364346952188, 11959349876622190886381031277440051157488649895018773836776860622450715877546788197836334577239868529908410947178119188739343681671610436055640349901450266, 8713800234391515391137777364808424262191583263090427510150907224331911893244284936334728098164518514295695826664947408590786555500906470663644484392359673, 11134180574585062013117510768632111383234906916157000172365317117842125169271157531902453528431835402606642971428041371920695019876139310840748751494664571, 10672652517826163337002387782583208795478924753693432954564907660500242525112627833939183341101880246958783456221484007058769382926806521545508340259928911, 11052213791816507764521786707929984417724955398072552720917821300699970235403878647749425640958128559421388850210410847786205471678928314136593027891348657, 10997086355911954357285260863710321076625143089230057073701515340391578579472483962825050765697366816433033684300108324869249390812625345787203357375505645, 9259378462951400827773760047163574216481945591448733806403566359893004965921114269192616272868594836774054422407031376231983024320153921112329634243718058, 12670744942332745741628454097348015719255102170334721862294873067773086176370793696694157936759535644768697193682907110309877985352047076219254412266801483, 9940286533203675368847536532435289050978071003936295870885728466328400976797641608266543590592895588496931031974175109736555507329484924328396111439724101, 11874878410563715804328962342618410397887694391575270407099579577083854140823236269744127719831500518874126854718998860005377805750045959302356274666444521, 8760902842013892706202918426280596679209881828540131076347737649813986635151072512142894706393493465980197591630117120522186656315995109507650394998210835, 10882824053261945770697289864571552333702327619124167249216771538330336539851262692345403606791233141421921281129193644611023781181459820500206304553125290, 7454599811028934726924349797748754018494352827091759081718298681594368701885229607205368227063104674468619223989778407520768628711709924139840762344798508, 7673408571977803421923725270855779960077566424605198139315219837777107190125682591505651885807015887026877246652670206275086484391174466036194759233085461, 9764314620056331134735434109242224517090029667187245516734910300002131687456666885365595362823545736444926455962200022785336120060535075113911216882084652, 8000829143730379818306183173407774208535860577462923063727114159812436011014859941613866952333492839326813915853698689744314644064537369333691286985962161, 10195654161507924191224577052901150820643542194442215265310936076748754918495242252869124423389484872616131103146109347861246679891685574723547330988418683, 10744712041578349312446779630758730960762975325295669941382941777740737465530944400680211911683841701220372873919233692500372828484253039766134982834330698, 9342132294080944564417767794248346772584524622651203468430082388878186318567314924340811893870840389084281785786677364979532873815510047265428358334142244, 9968491906009711132674426520143234556718655501605743603680404620829540785128780325250260224975409994847610820575637032941851077120448225211115007403023533, 8054167053434586385924426434078323848045668917887659074083356936388623053762507651545016267570347764526827603298257430638961704127444872505939903435292845, 11268073099594638989751385384877880607150664405478249235172623883821745152743738963164324090215811111506421885956169389537453098325923311680866531493037382, 13154007080520176004368515670173789443674181836876040273043121665621334385264602612581965665962115690005120079389383201473214229037752365307042263031968890, 7239152673967717720245958533547337919184552072534618290405473820376926487623570609775052709639113634342053313806770772573845859921208408832610007766284165, 7317004587665687405477759032181045474821663897627906437438772262468232586371432571893376993062848683255953572514706228789047872166666975513023714510798998, 7946751767847232148716608741180129679429009333451629867228126367660849025603350862478105828706577026380588532952378913179187924354273339200301415844992779, 12139348145684697735346696332867125959862788480821836851533177971377538275591402189884596118021878953930615037428724755806958033899027001615774290985059325, 8375342021368890530398936923370840532620637174398438384389080604938594945412965944720181956194963153622036065851894393757963923852339067182029939051964345, 7095685895077802513284823877460279835398123254012827253107720758619664197288048475028171880339939415945977650417326843709550050783621013665155038176094817, 12759538435491280914283948396202602795181080560934308784041234028703811119465363271556177715649425027399313630038242152814490671994726555961980519180821927, 11406103055719349101611473496401686906969258469100336782400837979833356291165196935115057281367332707583672394025586572405831445446772033522538830045119291, 6706957824608617904015230182926416876278050606981055838523060222851342039773499255262676120600934486993694037559110578986294935400117663539156558098270549, 8116681431977905525475261664164017064691417230047121658582699342266461415653830852688333429446620736350894839717238921158699630205786597625618056603941061, 13363655721358738378731925201803521982419994743792921421625745475936619369221449151636682138046595402237297673762509119862775992703320581819811466502956112, 7243461905671561223149044115899634428754067764871766350134852603725986710755312941216029623289034828639617414602688224694122502200197004661641528090356132, 7629897642506794216614822180757330840924585397754965259163764398977377296905023207670266813421348572378172673483308623256337292671233386999640546324745302, 11230186414421152421513485242505246798739025958862376635412751985784872171924486231671606405602029974473193107834270702242422630959052050906605386144671051, 7894246900051463259721204728456954122636442572146670079460099627162900155262918361027044755175359466173378141817737471886793690513570443130679935390926691, 10850679393815069823632306808515864071809629105311315015335985146130923739506002923002122350244641953434640665020159203453861930607038231337991066697065356, 12992328181815140376281384857000810530067703511373906320617748662010274822711360919808694932595810258760221942667078930849436891973957626919026708281222426, 12198730689009751986943778352077030768217204171074610573674148163372883006343183374060073511145692102299087970024432850325204189616250341710141607770516295, 10938261163018397220835941049954393853469419471549747759410469046282567598498145860311779109293721189456622067345991101792462701377592580887083696745190087, 12838262034378083737003873818397431640361522802784821845915940876640465197245705221543204077277785657227214047004681556349041437821384106381792976465824189, 7978352578642251592158857639533124529882260946078985083556853653692206800423348549724488795887790590940438191427090819896668865271868294551636203946837107, 9028992793088939343924906597535164127357847405873889408828160346496143790660326298485824352129111562795442293087312710240272693277461052147688390357713182, 9768860913741139581325371467147936924011801217538853298781734814111902492066419420014075780562575666622645565006188390747787433042996969300778215149601605, 13184044500466062368350979184555872939107478147449313021987665509414651659752718034265510537469260204575678632960233408297584457726441380810979992507824574, 8752281370594154967384140828317540591734409600988921254294534398309748528857807357795787545437641686810967016793514964864139891993118929426312759472698197, 13210260993687275837322876872888968304958366670930346384532934546496324912353821635981533617461904375785973194445804856055709294176935266175669129542975935, 9954542178404071015896308465711071080142350321244669612247010468448346748225709591869448898752052479099022911022376226304527677233864899726848727925336843, 9112588304976137706747112647488676859266706013410076656230239026800919969369046417932889837040560420975435832980361538366365667658893637054328008408333949, 12884487968232549194059195082712078172641939283528748103914493441347590376730449690580858203539788436175924156421657226777775130860560315967413859055503981, 11509057645066914427289705951422592296041372429030059922430226007431746284715920510172262482806158634950041986103583373545279494426692437098692102371257907, 9248822754928977323183746401001258444472691376682974416293350711457913420000562889571138259309098308682997109825580833597872892771022457569873916157557814, 12885940949471392502219181524250678591866698575912075164277895891766259512464073582202925232906018128556643078966469162576944638680160783546054033618266142, 11840029945413806918334797107218192110777612320642910467490574362320745770602510070067121264495972919653580153426684389943375557917669937300915181440473471, 10272057427532725454858619263466714735756223355884246857311194445165799880349500551408481338659496041772428414145843645652222695497763380767438612207360906, 6837020171906240847366641882180281366824917749082601777947757798030803083820673536126384955465809995834057289723048235231695942695813575504259615636055305, 8414736429107930724145866329896351996015637364827507939128231758964506091833977854969435354848806484625824968753314295805107335028313876568517618595955262, 7036583608551513269952191589210097832117741779015734497819532869013916774402641657487905596151450314190976955200157147794878261943144572511683071639340563, 9870478073613448959961953485710429260223154322560940037363495766377549524310476677553057848450934294590971816070047657003093033306613391840887078862801180, 9555407628717634361769840012860763782045171659753390030492327009234833599292311539946925193352869562150747926131792144262092348158188095203507519282204000, 13161821201149406552150919409908814415654308810979625364375877878254852222350455931324438395584525455493261178329182536281735602420761616257755968522526127, 11893883846150249843787844760529354700146564650373127426202316169666580865358814385693036948793756415282175134172795808098211015993009699759206823866088742, 11487409013300454931924058458397177139692956773765621582554012913968674352491865163559050488488889931420749726937086547894145360244288999792652643355501630, 10387943868642399206997199989123083120402320291774432587392665047008994672785101380387218209318433947459671207515604137462743253807816887099488549448766752, 13113974281506974205247126068187404561669221199113812084857688138227237562335149959740390980232959702517025035930292148886488885236520441332212367352421658, 7678016973403436757776995982143165195003351095618687850088557225481639635493120114400487695578598785020036584662567650118757926742525024540438388198793532, 11622880867938002272577419231823717509597570623966033131647695903968319409141430814961943749532131835795261744625896484841740929512525484170588028828293598, 9879545854516077312061995106220044355028565372709213786019194155310082954687354117718642447622455157041078228595029003075469354442736572922485500451941868, 8350428329394096735310291738341802337508925156568119723741360892344140985426548661285940669073224843411519783997898446793848225695348757748244750038826475, 9086908792595138685010581450530598772387472411166215226514075533062000676155655844756351511537748357548755488117365449617271454440963550324962705863268191, 10410601197119394605087070480956858510743706576301921440112473270639088056389512135121568505177657881343246863535192747539285808721608095778373889442856307, 7427537786640889266784010314713705847672563859470080089844747722842884178117241254241025568739322725772634681490115276400760639331514545436331358587750970, 9725837727464677771077352206673204310349967514007452305994495620460715440442993354336316016293262331721486272177144943182499787346830248099750243147242406, 11293316634906133765994628450779498325572673198382435856510557904404924016092155099217931876346246090552707982356227728153432443319003208339701356505034466, 9489698169771902760435745829962364123625264318278565321735635780495348059911563898077946904117620467600465906221186719840346283265168392092131320218277927, 9433283685974905541807101637731784546715594207808340043266960973839060426096953397589916880000499191077327869095742620353620753285482839176920046200618506, 13216274641224736138778027310461611185439621603528952109057678151714987446162309842836057168154632271690621412429726913494812552000270650622518002579865208, 9793247891964561873966433050421361780432553469801579174679539096647732997830273186564083077167764683390763585088187536602478281559354862438471647609796541, 8580357715414281452834106803713281903138736880866705495068206955478338197722287666322146966105585699736683690466652182920862048551294020838187884222713066, 8942036944437019063411928885347564748746426482858562156168232545467106387944391401324234735630809732051918684088302793112556103158394538727150800171234277, 10011534459963216352518703187678043231895177081893644289106595321290144914645189012479659201778174849972270940673079189269766829891054515972395084065294015, 10683829848241168541901616024469708100123068585034590613832469345416807549399760082661889289593815828768139082137084602607807516600486955815369469996976395, 10386501316881417444395407255465841712188966269096137518735554034979890820146879973897982301466069300684506250245706025943718179915802110916400247168928907, 8052450922302657747513660649563435988929390497908013343552505784932408572188769780782788185694360021072126585987292027481523762992179546777812940506635202, 12899781378027930134142931257425978661419945900627912428328016239588522747314946166666688534113379817551021614583860834214407610962039401114345068337017275, 7057995933615737927720038278416039610983955887271393484907028459898433158102663263986499448900862248806340193061179431931120439073768510581458840538645777, 11468128779338977627454991170077373434242662956982112374458022091799685205403739958174924656890782545985379300627220047333243221728273141268224705661724176, 12206783062193015248733718432107818979470218981382517484347399166581995220414179983209475367874885213749853792828665165419831572541488299606844410356929672, 9087644374503936422445713042262519495354015269242378663845727379671593471242553046277093282282972375042232692944817557617072928163957738086516902072926845, 10856912422509010409287844347820164231430023063083550436343906560612749384883302779955525130668557771446978715558633981721919462068155927788670765106120635, 13281414084154167463353150244480033434034591030048418283886193725790240477823155624718242265381815231284078438367030292015583825485238265699726875464138708, 13100735713929425461393585752455449243360997992484593200643212150313970813007635702752078078959005851428027515589627868595109359794717741936626684524262053, 9358546290787177499822464635126445828612338364997580581504220924364781200731136534667374146693178767296480111217891225208667316120724954786593710099385040, 11641941920102948337376031142391790797818052483113770884269155817903532335408273774257071126898619182129421203907358137604989652103236178165798191782020408, 11901865501750504580750552789852196780602085718916531586857438483441274288671853735492473647472323280664271144023442888491714562627296864368310292915435403, 9202097195736982476865652239267259934079977330899940536217069452795428428328661162806418315882755882624066720677313351717149143260722250323896190572845357, 8715429250935854863560034121423857388672722049899916597596112361019380744187072603062825340370776066776751087294057292937439931072821949899309299404915670, 12649300588476492188432266169004400880223674588131049271240572368905944588545338507988814699124640761965537204527873738494814235248352773972572647765818123, 8078448758194169347817404456085515421995635233850529793655274650917149507961623250702464671696315766331341429609291883028497429566927299847488655070969639, 9919442470699907135885936625292147291647655068189415853341202287200708550126235102611042029923751239105625302100478069117981855643073974953044630421792110, 13154112393366942311034337871684304841281306609067360467242038625507155197799330414153106316636708269577580362995439938526552260535225413916212222162801258, 6728533096895170728290546991968071192407359694551308158358159074775718711000686767207677210839206375288937150858177594270288435184864729630045664860139015, 11942303492885686960311133450578089736785328591873543615300945642360126758856501266184258298279818214333681673127128805349186712829387381839120785802399267, 13345683431318975866703169999993354304695103915856944893766485066955225916178282592261063464759534979672697159028208625003035112583504541391550898006304888, 7093679947096256544768097511035763571983054131775430797804996243523853145109325731007515001511901385799801064540291932705255184803038106705890061584166512, 12723797634500418612920650968763516600198674512720414993839551542952970776995975419777202130438585789721243418680885897916062201958072521036598596772128751, 10778109694460313425645579717661983852614125557957609223971496828356777326102046832865712943247623491438144460075962596001805881410226359218084570597412056, 10423541827372084142670512035067691617318424824756351976638058233766877923859708198312874891248181898744306366097400115542604101360727154921557885211720046, 12390616653022677930988756873993293017466462450470608774075888659378445025858534037207898876108908025433889565881652686192443226407297376837365218610153272, 13214144131387153988631995569445800808964986623570679523774605726293477092793736732597097037538231040069583877963619224374101000936973675676817140444904397, 7240028537725443231570804129133776489715860365388073186684389462471597155276866433636865345858256549361173340368524559558955818080501278546897672825685818, 8053650032502804075624943991375584143062863056584587112469847155079407236937641290823866546268310706602594566013969573660972697726115305794536053694685921, 8520439885572768423963931180067130863883533343052593335015818735812333277983033346539209049444443308229823879778689871064927366294394808213987716359551096, 9126204548092137976767284546202004027799106127135241221070264590228289313913474792887574860956593352183907302039741847540259406161659955202949609809040030, 9550907682038058714386739422314349636261045227805730964745676193375541424135400841290025246935937974729510057792687507264874848774652208036921648592962081, 7440642854357776337048579068617117485651029778879405706828547386451294213946889033215743291208426943040864939337181380154461744004544007740911349063225729, 6819690117486137064912949975106764274359977431500467109505452849487693038122366573681979680015517899373719198388429065297490031210279735965876374124645449, 9679099154386234316326418405202781262133540330721787174005755795164334785995166690688239053602657612152547488765376091930401937590087701772090541312930577, 8534111422080577658809717482596652587656120603857586950289649977168198794038703111510373789051593498246098519651565938536837972350778651102006539571216980, 12840421595405256224478975260362230965996750667469327451384774681106694917172176439246105002832300076390212312140177995553912757222180940339819232084004573, 8050226088150179999145956381061276759081257932642470610797905402182678838915273907677299566290753284028936100730343885276855050321002671302222926927204385, 8248492535425213697999433714094882905437232292389640852104774195042234348396693735829092245797516767805852999481772588819354100795221567840557647048288620, 10630341576317662589061017968615941340246165385734252728025994860361369276448142976973805331658290633480845871522485843968047595697181140599390545396720079, 10840210151261741717085985050270986188148185310800509167125706773849158997207879928892842862164374557632331077160035055525409908068817740963417430673309072, 12180929929181968007320426053956887766917181592525795118306852882543664453492839617350106585041623437169790598962646880125831094338324544759407361644646246, 7617834830019741569950617654332572094492426813235024439866787650104654643021047802893701833732909520076331491365002126154188123051289098339882428426324453, 10344906677353185999621937444922859046819863617750086540046173966295098164873995956063693773297315537658833449977248185053017736320947792190018029778504511, 7403905336133886280059955232321711450793485629417965421180669920540194422700026113781116210053535247132832541523049387589495123121303222413828221387566460, 7333040452271211065397208154116437447863934064626117777894972781203635927630239126281119478720865523753354768417405994903814370876885619380484296435808248, 9895214979244478269445311154584597354155941059435635818553627404939999309472377106745725740154650139115102956621883253937150294799523600366483321103026549, 12451232399704989724645160974285013084806098936526254092803077178597675750758351020154451133923668535989676733271505618903665435848631135637706258869227711, 11870669387160915420257152850248518151229316682414671192900680768398636432904557530055109053328080650162521964996178976598158982686938327352583159462042814, 7335490981407520030206384849453237410219218713178977632387453772779314594554506921866664437289526317764128833859796270591870345195215961335982397083255799, 11267169268947272856801668608179257225875945252447145087738512845074571486249227988056917205059414957383890731074379195337479944898102424352868548731552426, 12430827577102921000688691394135068794773372601392001866641407868270360828050434319966859441729571636308351744175900833485367998694239160022946227147286896, 7248669289347255212048832003912910492422003701685298530168869087866714893003193868754769014286855001023939047950742675425635316056242247486196098019375813, 9810689298720253206391958707763636424944526273886880496277078768414785708895556767707021167338223731300354453645637969600743559539267257384314338328037907, 12508028956672792201180885353021440167831708620116022468434833200751434177565950911664973589885649095102248931640201639566124657162507475458587661561791342, 8028105696217268794369985057715982795351143958981123845409809733046123730095797393805361734284163625064033811941819476439872758201571550218527551379308441, 11430320114587340480828697696716295670619027723099658665534540158604115523522273290757091114339249162131919936074601482231823528085444346352317842005655805, 11661074358687877120802075152417998220658510314314827377834003024694333856112615397666455060139481149875353977678489346110866454777680122895106162043092433, 11082374714785522271396571674959364898892655935355213729562550443247853722267290700139920866650405399859899792410921799855431442676730936517769304958918439, 10019961785412835302533150321475384734650520002886772524147316912104346587245355896281718855306840621917770557923602379815826907974348862075149012883972683, 12636806704090790310902646028877338426007567924465335411146557344537259682860256061281690029758451490627338925021737269239963700420791961418473293905647216, 8780921664732693360064484332991669546167796076785324919923384229602620867652892909006139033231513614734933075302018634762468669278914370966895652837616579, 8318931732691378617057776159907381026199101548707632193225248332342935783775824588681928727632576102149728663412751243645410203231947762027743898238398115, 10073314085791344990617472560871429432279449918482908226871570220904789786330815288373588032530970077963175757898271247258169175910620229645824063525004907, 10589367166266972511669471247453975133006823090461509966480844973371289930664520082564512001829958454386598033079420324989085216844085172427186269327762382, 10891886281402591047218486831781335343418974149448763132472938378995890906478644634903528784801058785782870935272031427534064544153347024096738051570078188, 11999016958564523544649172910441586713001491137938675701794067706947677643418986173362714498441071726502468556343111730939732562727391337288405851025685307, 10038592395973711425122226721158717956196785233928470748946854911073298476271370926567836129177582353371052286411799558829443913447052058105140466085457734, 9277403933471415160857999616693547183627008195140920510632203239076828404680524854775184046239384948027445724894467776664919779733555915426157716953262228, 7866233010123947810125020909329404359030991639508354245781256153191896865511342150006823940635159243142089477204325286270685308943093254303485819985114204, 8227536329083255135504737451960160869240717715386762411495964691623572601944275902911609572185172553381915693496602775637757249688579559335692495285625592, 10949820602908207578636868310052406717791733196690480252595813194626492065482128622389570448202409970405825438211087364022490623659171556770847150849254295, 11319726536972048530668730590750791293555082869794986722609898658405901047722223433870817988661252511971529468508464659650384451768476113062040466516233158, 9507368416552016919906732772811556797027945509167320474764665241956267451091520976683458518405227174288663825884203409392439199110338784105196303596846329, 9403549966391431219266035461645005130807666887531106344667858296659123074010384765262791270748889535541569024046883737927554040758438250689637034172197230, 9993118469288760204007960953471334930317152139818029577721545254298740331997002483847550569140440198842435855387193438116930714213926523362677859622372200, 7976886859383559474100304518823203125814692297000447747212681880750334081985806383912801672701699913669131161038842307445403085035978394540115572139800560, 7944305846299050414738394196622465849059448410557456843944489918932474240601308299101243775298795058938370617827369056781757957785365715492884383126771383, 7654068509518280121759333833615136766579798223611745432711397099394478071109087141555264474207207449978716356419884200244457645864722546598832855888777305, 12975621656758766992713374805071820941526449056669306156364611490134277142040988477067865793260618787221048038627230946564589005716145899227826476581039178, 9522154267720622448565046352488393684912383524230725156098168505033035725511494862101952100228325037779506806684056456580002488084086469415304969598916808, 12112477499954740690411513558309770736294529122124222471867540850304562021738763280765186695588278728777655653239595072463648730455724579685275581026072803, 6729712838354523777021851984654683564235312909486095561588684079507453745181219444391181549720162750148497050451612962583995816989200314935669453006815914, 10552983052100386334186489319068266412259356909173751618198663186232800989793913231802677944260842621058360109831940922419512303977662314311010487286955136, 10754897920088864437664850042118942770637606691983043518149415985722669898057612528434306373846656713299313660720170185091996762919233082012250426078584480, 7837346671193529921731128598984458398751439205085803745204593901587873709287123843765599855914396457272924556699124939648392053351192907957630563039390971, 10449603911563389779250484136473387720593104139292268659221908370714268630821982680498639623711568854136453980235486882491721805297362663926557728926148608, 9825632432728386970831720791447945237978030284938627349506075967146919927715187128480702522860425535571079561853508389536185419297998695800359220387148660, 7154827621313479073625603304217726206395558722232456118575199712370087747224324126880209594694954201854603439039430157491985566929470451509946747802581806, 7690116921518355664013582137647591660614867122810512586343196427223900273527024599036154620409223810354311568886956456683954102311030299318930557689130017, 11528017622873901890722326105752559491633149845942781985862741395018389064891346384364953047277200095874247031571869747978027367290392295250639014200472746, 11294595289497268782671709656912475701127800594424483981883830353670734190546149201211505977315174304011553046031638945678467349196351200701540145234747627, 10541579905047319183337957806039659807989242961210366273794282752899803036352602348582619441613524485278990500842649067929095284018730940213240137774197138, 12003157381079704247794922292984481588770046488609594520467344003893163238098717671640224442600014972045530034569632023190342947870907931056977864520010233, 10363246272037319980274785806436106464565851925850980499375457305306266661465192440260564985688546919888901041706924396693868546743458699398852442495208684, 9975393665920945183699555331987413110710638650394941810697223879462129393686606473819476911474288899040574263745266917965020160852475199086359777779923357, 10608422952742963576882124861267920794859563648989501746864473541140252345912842690431512564138151028897495066346472771540750236998680308997866107322918424, 12009021060577161222322591827603919365442696121805060601734620904798488381533692858910363600457645083018809881114749535397830251125523534113458688441832103, 8122658777621689610278510474305804150760336058504077191461738577981690953767532068472728969570850863018651605556682308871127108743207272252634329210778757, 8384652746854882735893055931304305322716115799154659961378047630429191883189654454998857662583637298714989601223161861592831710188407660318472257406550583, 9736892929802809482651057548892162262636110725983582020019302624585803980261682942749052248219732232436114292204745757871948933634198755125949876820084905, 11719750118276924327212364842924557047747167468794554128645037640109768222231472329255042228623225901156781142399423170845626468820730003625013981986506661, 8792678120079418261417428807583566647690456857180041334143111908675205197581229225702600916305920243746296919951315003069627924621403808450239313882302529, 12115456928759403934818184386592785722989603438892849241076009140445910557159293484648468641472545326003456050445886704568117359490633783231718237419534780, 12520130204978428768411510587849482698369824285378131129733581761148332197774657728487790879293865426228146064613348226215876730332511196995672988059966329, 11682312790762617516755801589618095533488941194671039687208558678227283420012372608029824434788820481939735609840395916999453999096018077546355341862905991, 8311141296413714625581618796803099584572727145428553382924911568673773961316613396593149687564507584747059996537166808129935969266770813872422868572427876, 7052235710832500906716207078684154847180279787060291752736768662363678541389815975000616433509362469406083227958138654636001715240981932788790783148748444, 7718390381262931034927284957687729739244155500501019863635697133159142099005790963958856545325292659822869491025355688339237033336149399689284507126798678, 10018035566862579217130740844236410587337910052337462403701867936663173893300990019392152121501686992346112953976419155310474164624120415248977532562140902, 8442190930048456327898472944285040559833837503179813531066229755038046102238779060337787304310582758967192365235406447193234158405211307012248849930196170, 9225139587383814902064428118047764034390757190984839366696999819818128416153338040047597278874920397097427509046782386099390198423022535770020511888361264, 12104575279355545132277192646396906702411411712586521314090584113297193886692670192215286047310037507176700351090934059100836214512719862622556724562597118, 9719884596863970064986120845914715893260161243150062719455313454988290767996195032561146506697233812348812279031924675483896838243115461501552169943392605, 9394913372731884499590425171422265827368303575089508735326573239351005474872601426612376012408692889162928365128440247786336065300775497623565141153228858, 7866978803758026418046208783963233897318154222452348915931075660849692199093199544476106476956888563453041130751429324625720135341823239184609586867335462, 11611403647846416977708021627838825146004556701331725558876240904271584379072874916276731576058043141594197552163146357332401693819623256450433266940355702, 9739017284073542812417030041993036726605236792277947483441777359209601308263540490068986008406231023680207786718823016073184536959438649614871231802757206, 8104645849700881768765026740329198716469764261029190256109965638591821189204030611068000231418532264019252365808845997337198264237836261429091607549937930, 12571604126440318959064515961357478554286540671781612844706715145505184915504257358137606444604512975413148235096172886063289189095854856548584813895029359, 12136602077139014301905671762040083031403472506074049134824586729346232839089376636423610052720904531117193847528901339610588211314655218301855573091272900, 7439977749206185432332581600000233561471476666838404012471373134093175533973685762857027125650734655132135686999574289456477058583095324702943815213435738, 11631138282927546389637756612062964312962350471145919784173947466746784561665471978061690430022684306123337373572328888186204225084116324475744913033869003, 11769367582838889226754572097677727163598036039826928325781683619031787696952047957104135346733170573511895625635487582611268619267287893245486660785029756, 7725340929897505859457548301797021980418070318790119658774384402625742752508054440568560540302552708854861835709298853705138339507911211286229926500587755, 9667989822089362278871736117318742390572410932276207589807258382279539472040041207043861586545917135152740181633941018366682110123450512054670425437694373, 10810974627898396386441284310596721581002432947144489627285742689830688232477288104602078676635075281563714746959527763425355030715902297440959371151239132, 7318445431895060850687525716599491619346585767535036101300128831801418919197251596589952982021623941159999753015904811985424869907193486996015417029183279, 8408815864648426035573038425012983618682790032966215426945297844316374054278896272697694158473100952061300439207536952970724876958798674288691381852351907, 12024741602188119304397233606778599200115900170944864038240334714847746641809121071901807191879397675464787691353153395832150821045732317486702797569053623, 12330883208603966175365524491109827901112778207622136394657829220441727784920274904454484317335708509406246804330019864370402669780726550454805354039845736, 7540090440636882064307549720054430729725760174949257524105012139272132608493480186238711391160911666834572798945532016039255021244505075928376570067651482, 12216557600130522840165674051491415158997069317129543508367283917009795565739697686026223624935476882244076580009619418487939588652582069671148217958559308, 9503751769501044003088823796197518377940568109475210370472267575765438373037101258338868421222281852080035602440965385360389246874922214610443281526134656, 11319055825719288050167904868424160856091908864391902404271415873141956509884065374566992670481061665297637903119244840452914621344438076785990102053511726, 7771936076620780399983284881600673837907849893955494031338403197410410399712939743183764108911963063090139022333746215893994284686606387251735185479188561, 11112743870490209651813909001373659304651650776933064349301118299976978314748019987701197677760707517051834718401331628273708499947220682400445238356859987, 9786673421440168043788578691503900397944111033698850287047726707638516458368786824050723049042466811828285006692527805153879063131458698791047886753308444, 11178317981412574545733650806280315833675884716076361706914563223413041955304003471794437690560655884317639421602036759146746385388602755390890212662484066, 10498028825856692490251827095323979390692350604715861252569496705370131724222362544349862878148408197368722562830225806776086435665509419028369013029273350, 13142960762736230998603470297772020158002356686861566425664910230556679715428134559533198180994379268899927918801695030330933702557191555886555918419445806, 7593938346620739986156543498058505054059852310887462447092144053963102119073471965885406007723295696109692116206796754604162117295691131062017100747247397, 9568833876565947399114008867289645583234470262723919870312670885539497411617909830702438970643489717307548398176023351368701974653155659191563966759192603, 12627214774165533030147445169367356101502056702989509243754815812642214762915456618017662848698105228615577014798162081763835339270965607728540017745286131, 13143947088694446215663634682492541746568991818038151079223748616963239406387831875226591156247257314571761380359607430177106620965615439730498061591900816, 10247653788515455464541927243685317044391012941692643025090884340634552372322067973420750917978261401465688687777919662588367610143295668039423923054686314, 12673425581500636452984529911658286448629587800706793556955632654023241284743522957241387227630822030977921957176671052765557895209648404031119785960979766, 10189845921441114737051911526718134649936331800644602635870289911638398727735918172062909766628771705053121122435385221149448289672478946969257237920592254, 8107276377917047822887269982788903899930081926593411206127981166600230942909504176699123746447914617443727851546347966084750077874794863038250156188609257, 12830741726745389634567375622620297890714424200467208743166830098051560756100183725331197483937874510563594794328823641120710406763993881737633361344201355, 7314556475681893361966614691686304284179933633750602338345715358916203085525424087246889780785599018499798631366793416527235675930361707568371114733885840, 13305247953800373632230732430595471486050678559971068587351030889429396800313842412960569491011323028100573335237843265762708755394197510116406714510242989, 10103863939495205171774823434258039500535693159073684733762787249945249620105556183448289288884845356411608334784414659759505049158928919785665257132184746, 9185110027272424546590606244058506210762040914097130685598767140926204163560238990421253052808642350630398284273671734156002492317547707069619520039534902, 12413894671398918796716607557164468542384750983058027294132765131641353665524112928446858780014105225140477356690820207528461720560992094336612232931527372, 12504479968514895069900692329096755404794866083004995517141220564400851125106191448106821720663013351408886380327826587928481990672207651483737152859528611, 11056930039205900265000238305604310639391527277689255380537577919331894854830631575282888396300346729226176723068327535847472975288140387386951603227293378, 7001781113797770108508107186732628526653805209989004454765594465107300921718892867762096980825667211886328773599221660189543136406977644896913228734145851, 7415951511697221502183910247640956356932370537996602260616666078025264355520903057565964158575132196015491667871248454925238869273702918167983206518942585, 10913235812639641284216521530862686885991799293670451381877254141069555339568773949231410562195391300214617394016490837163167033490800050062406322760419301, 7812066784856883217609896455500534039932753182278317434329441805700785961221760249429831824769017328495604344168109729972206627896625221682747652533413505, 7254699017417812990907755207283021597698294568349666218917337893909951989299026292450448042430374572000159042799411322203943129961672462655734249288131186, 8722380001585453257526667495298751725246345021647677473511772696552192214394296104350389063474061886391237002822545572539983567361077385499839269780859567, 10499842811964227941202604300833883996588905549731337950202668780729331784690014718691544657564823513041655128984888734495197534878711447143647740741055923, 11273766631582460139157512265137115225101308444320924824608549220122690470053025866382824180288600941401357775479248261857663255418116277978307366808068285, 7725471829048774178957361392167013905137389566082560581509066027583354317060631585289255121665863423139052226383705718555726697246144952164217922599707127, 10463540713624532646401470856617482208819341496285590514048271158966961822989281624198616692354403774969456818306071258367577923940352626688242963399188003, 7267521812303651930003118584226210663710810804742226743755687095908590787825714236290063446465468872569452003553736790381533721910515530421358925166231602, 9507561313779904895942860601264508427679966957090320851271585645106165149669663959560602297243051329692322276144105028383456222154279476091593468122246924, 7401742423834267209246114777443353394707029473016505937132378943043086298865053918725829567793929795419736251831046764355696666829014930145107135073890168, 13306132454434925497200003833830925700259016952441992796331378125396032200061057765409069899182082742015743943902370052054551296838383361803267238687930790, 11573411995227536647233948333114094362452698600684292960631950942465630708158674787068804128161596160251913672092078913307620798192211546951683170474467658, 13389645614868146441075152526614222858838556298552323574850401033646839600317910465572975707165646096284549705090695343451124256928691511081524372248611680, 8191162170284319433517581064384052160117895982019619907660074331353254140583880801637000879456537417311758868293550044811969185135511147755745188415434586, 11046244313029199298904840125221331660437494868256270403815169163603166320900500445508432260990716592007928633126011033783611771708773028054011196070356622, 6805703966597041605180164049884704368007351316389446428649116505606841292517276620156238292042595944199391064231837533135022135445075786522045345366041790, 8128283468575860041784829211407816906621696311384558633974276347867312268270586410283628934741668111327508149885546106432427053150443013539788288482644788, 10853348307646873978225054263497012092453408065917179709023592848029411310516109948972993583346074611396147985081699034303809887290215200904530514416446030, 11859450315531688510505842312848537002042091923235766409062237237226610505280234465764617191065209234049392230724876421885467789547385454174686429221887222, 9872815938376102530419513621633246886118887895244795283564691378669235579389414344446405665323339062604187030792296815750210514310724193989799133488671267, 11329386500201708195751605488036781818718121692892719324664640985757110067828420401395566341755255908618299905320870414846133880116096537560434234176476427, 10771136999704034217791183725162123468758108499170304279791441854127941042041307426577259064920155126816961268219933345635618825987200412552493404819330792, 12465663653808460721462573995639987077653420396551011468353993259824639584779016061936383231105733354521942531108186206586996531538748045300236321511501858, 8819948555824359594099710857159226717896801039373670208920487857890828455528989332089597197681152029246866843295395467416146004889524165021490251158955663, 8353212720860946140361863702836324482097870169505964585921155419345189849453454176403671576843478650596298454408398659500583433006366909499543741735067682, 12589699877818716149194062868687439357889786182820247208151350645184901279884287221940309161406685376094573322243174980267058326322335218908239497031639131, 10228441102321506291622720905520208305927490562607839022345800352462710022051022024723214579439901522497132428089854942289089117966040543555961762389859202, 11818122804240399677210722664107888684056004966729480328317108937625109448769762985216784723636532432020150918150104523069375998146734359822775844216590808, 8823190634255781728062456497560958686710026778438892947715577545075302125000612001895442682855976184400235229302734292103173098045522617525809847804700503, 12775935369502833145105477617334770885693715749293909168653420434520448155894968610544091335669861242877366443978821492093822603760031422631868345707334107, 13100599692465916164065520582251656891975462820372439978525679271640193071840348485633821796667614546722480312073088507633274243428458912648548644490681311, 11077528913660562349682509841790599162717540862549798571400129573954785240607223335920141654978602659357842006145579330596115205251488144457120236645139272, 8414397956763959849964685099029126154431095749529147867988745592385495194574699823460989879152586105535721763080350037576728575046347830616538931603530310, 8312390328196716323998768012371203650704451241204664681056569256525545712677151340943469999392509998453957497626108166439938957644328581184514454573646629, 7739197384902284958942037524040114970234541340606380521769371925516693860715879842646805925347532276984477084381914175523381957689868881954896295974969343, 7338747031631008473301693976477232502377825975497418498042752163198992263009021607458269258573728827272470515457064518432323494904264287031437190872674016, 9856891011718741451628845782266319278741662042518274173446074041766032419560952719116314740197721677084083670098991190608878468611615115528249785698082567, 7542560801858429414364156064686695118413098353809825409665177410710879578560573298477888927956081970928709229220103626406564882653624958096721749571812656, 10042427458758656793266686653194152705066463445022392186845759803396963848443812273733149746736545054006692007096008116553162096525070010205889432856722439, 6736527112958516253524796232210135812594917126769287053443626076890047953442405044296828827741095127256997270710716509569113091906499472145560721188864238, 12466107010742694768124523399535147612922821860153923284952232813415740568075236000400688728994430115162622970391799803268572116669269507978868248034189878, 11276620004983136375738167577937715258813442128927785406586976914613442528382276840921848435449431144907535787992879727918428121524483265432292844942414883, 7074458826381871278611314769695793146413577120906913111554570569331864198166002243920429990662333813384292968552384584135882303499506027099550614246755846, 7892744768980974906233985340725738787404628264990575185232193861536470250552136481300506064784237828654130859684578597863148597181437670833240904290943701, 11119401050907549286337128294465752892770984247387467814453382105412718448581798646315763440568185416840143002749033384136540353646322853418296802898848033, 11340294283386601079006393719461344066087019958970545729164798287825322619643292239502155338635790719547819561605909358263881571474175311484243368397356372, 7362095896683912106049486279989839055611599413101930140223564343081813409788459341875800884557776267643695431195746612818257750020473411217098877789427513, 6762064643437613509882149810426851850125464732157813384519193937151323782768401927858877948312054268808311272530618648834585871777874275662971313717309067, 11545021681268590963570347539879863450081277550723838550520696395984950474259733888096969924611290955894324883286139128813966595451541632705793669663634037, 8922422370516517762789337726296888284092110817922047104722805116254822897111291733509251296663544072096840003851512517910946426002243970767056008061182627, 11521088785894965809401380617190127015838176770514337584192275805880159669966971463113160305209701007847258930552362690664969841683631633672867747914084244, 12745333544384836300972415943644831224066430916431362068898031176492667754656688744676035977418061398734288875892309767370092915268645930648782667805345588, 8233736940741101078544408052879560942504645756419731033328005904542170150323559909373799782871672790653901393835428191135538154004232827668921624345161181, 12322195481947932139865853543394836233357546310983741367694040834414659598788176072230827593155807463698635515876110659370745713817615755815157572100939552, 9629627693069015611498074236913029455670082090610977289448179838503086937615540327873768199766762794363174268074558604863447658295638233490032540648095367, 8192669345847103730969303698513056529301815932763125439453708463907887177287699077414732639425228606320601612595014180765160279083832289515562618873320201, 7061494772993362152013461558836469027853206744702033394543480293914076625850115192996140806782169224299103528947083334441731977593519841073515177535592683, 11362594656774202452080436244771787429830088378154146374949515151116009259970605486991847405157900814680884730267050943424012261523824254360597526336965070, 7077646908162264289536425336429803643008618806876517291568823521354049970634971045725388049123390290758398144008691765418116305759620769043714673446505869, 8901956714671859106239326981082697080737606940061930734609976271218319886099701504714680363348444610386474438653287244435014146594538578209288915063343024, 8478889766601577905626667946686056539383926562500779117644290243342311983264510178282333434153105048707531926646492631571910684567820005115632242898833472, 8844650361233844277139755393412630047118269806815306036323373647969845855687852518825834171523135811299851058938814047887617685391329512761837789952586614, 12952815215678220942624650893725942016208077745992626650716250854982968900052008095000877335158283892987426095123971371695665489203836072504872711970119679, 11476910437263589515664642081530499728809065634772128306627037441213964979220041719481580038473002905916359019822871585295794165446264368118565896157889613, 10946033008198525090565612664709458838641655969736623942827738986008333958347459927034881501912283934386787941580149634369585522077677593136707134091729784, 6903956975205550049491403347678188993531590942999702819680498431933525123265550961607056937134027689310069558545528547906945184831732194077062217591375748, 13183375748045659954685749585828490765093119973337667454208548756421827220353235611185539266230363169565463751646233506781710921898018613172661394859033908, 9471276558829810584874786199165112403974001026069950136642094603374876032385847131503146638343469618500785643484527489619871674961762351136367294456474490, 12446790280669647184647117454365198571227895757879237325425449530361461539033320760956116735601518201631869807466983364266209840985032555063667242541091644, 9441546911441631995261202228188141261078568281348921262786659327670679874304303878926308791768240716215685010714520656289878291851184001119993257356133870, 12208738000668244593876259450469251566679254279037876243035457012253396599959761558587565469636786499702018829198303288540319317366540874260452350553990466, 12203895481322375650511667440787086801462251934991618688380893537243880224212833888485116615618664665063675550571626974428078540163630143480545339617279858, 12504134496532681248467737910621189420887914253253500525060060671810737634332466387281858268668172313830988958495382706849779372568806964975508373283015209, 9226208709293694728919291430987249340133381047750494431621363441174445503462270922164480132130542146140158585764770270743352502126901032093960396538363377, 12655886054762800775240503618149648209836835490532658330104942362211444519459208786179298717094009652261040977757633764795384798876128450684940378549062274, 11956248486247390249577160686072947591549950082513817478653660861723343598954508058632427916943047966537283668738602771059720312779082273746321449512756127, 10125914201692997129504193821697144167672639686328655028409181668931146143321233825825892287107091068560890423971297037398479882022062191985266332885831305, 9940627015089551776345690554124477668900674765657217087717574309940728223618211059304798673502428804996908916887252880857441917532395346249579980276370027, 9951109751252009411474907744499482099083473171040776360216192306768349038337344300528555748904598016052240654411671039861068694177155580983839170869947368, 12386883445757328715524015108014636537545219212419577776214309816344396692022851732944397754842250393802822006659151016050079969620424406513131174772809634, 13048431999881102924100137862995757853315079819829426659066294851607357886535585584052469136729601851162062073418631978468628570984667374722872917757710689, 9333344559044138603605686257496745633677716647161941350517955458149353429457965064139261141837799662223066896709406802713532709233378475409623249928262260, 11482787030494939690895922380443421767258331254107518366507351244627184975108556083064688711269002160333169636828842682511380293883899978961296352165138640, 11863736996347341491382851294016677098220534700510043031750813015181668397985376365508183553474506333447178321375142868391411496835099059449196341862131887, 13050167104995108464015639161762699724319985015804742261229092554243707982203782242446802765752076770644981440134918902271737529086890323980667128671378802, 13401646968259879304394578903522633077727267166513903611628292862081601317751696595847272338368056059703591341658698285515948346556559153900404214328319482, 7242795428796190502767894898329630206068082333138490172052956664040056238831597150263819183297496604100788227294397926881013343826527980928725870014339876, 11110024933657775903046622457597697021263288862495023549011546281365941026337670997480337558134049410191239412819147695952407992698639362218723170956897919, 9575286247057728582330605485635757495502895393140299008250932938902956225625026959453663047356840014040134142916068233954910410348016527812109694399381618, 8425444223467578447261512441794119759299167104472824741922293988958003335634511540761096899483555111654860662354448193980710603859646963193477466705627815, 10725463746461660514032344483601728985997998712612054853546657300235100686004027578101907092198018934450681191152930376690002924852450939144205214258108670, 11231766131301298535849488283197107172730907917531672263760739268496593764125458069552711672191075497346134522920398557036448036842897050200509652554634681, 9565916970851796401885780141322140436072311553046670529543153288957543450464203755497741887501730980330035802688211784557528710577852636929891962174499134, 10192512708922211909409913272901270044305958901446557059905466073819269675429806848195729732478657724276415748551728995092445362411655591540166960758358290, 9876985400538634115870917106175567433039387029655577452030487944149695332029212031676744627798491642743311502328024796851325176133623621246147621393435878, 10794239944185207659948851750968938836412660239162382178530958885139074575057640305737606633547864650871429991357952509575281695356884205005568708706277090, 11130907694882256561518287535128420003794586079127051178956408399518059333653650996757014959644073540555168430331568701599257743165231636560216642378106727, 10611613320240755295631398119611049200346200498025633208657231929947261760584864854695278006639764096023370292581796781435672939286882473878712371502511661, 12963121717290776893024383282024437404115160551989012791246478623677117964033531902400495299264062395772074670033324500956924777519520861651916345310177994, 13223968702637983616213801718246385913337191039739761965757686207466455784911322471006428560203386236594789624269441099377298345830119329623531794962366244, 8370112398979725091704623908833917644487594708929903351452208495131910883301331122116822578408434587865900418887758891510828992727706239617776384369746058, 11372164363370857962640223871324875857850892105862274501689791835040916176259847690967537618358195104376740252307391827103243052533079761371988495745789279, 11492592376460687854166192095489668743378142610619420978918752250240114445899311129687579103942670204701537754501414912271678982966277381281389729174992962, 11119554285621404510469758550846948411583033315560631772503658562122517115428219951690411757421413696739726148744394186874149999977177244663614062531578977, 13232567556670675674987005406727869423487102327167360512601328147709062962696959552101487596290402940291061190682946066503600410795051713440342938413802599, 12577060017828532265628954803573223929096809180361269868045865337973674491810569053504900590740146236252014652772778391944621718121648971837164355935511084, 12260179164898570376209781522263223175517023345992235282226558801863911525264464973868033786784173988027722963814371789760322897432317409193067799827487491, 9089237981270601508918144441549496108327269154506436262955436919447439351790898499446844400576049542573226757322353214234454668005743647665240863578208328, 9354478917499774994694702689750675860062204339868958341930286976609486249714135659471809235727462716573095859593745700270543508962601323458789690623494776, 6733464243379041663386906341680630112520475254949693423268163303926650637825564610317771393358913559830397818255694848374291990967210221648696768983624323, 7884539229390629013418864537418705685629172551476567569101235106199473527901135366428179740601934570502822333990590601432201905437783003674060378196213049, 7142160129761604222071610537649208774443660574945944448984585089941452214181188681692991137941339665476435986514122136892598552274797018787516097451159578, 8202619938093151307972924570327452436165211131864791289741046962718992442819142418369121183763936730667808818724336805002649704195267819037469244952601785, 12309505757000644058163863789974432585656140511723812341638451750480125795339746831821242563912878380338873205829442296681266644269357350364117154480738861, 9427260716621805970528638061315956058690139676251884901210286135247046302875494324918475611121675204837605907641348106383232959617716690237557435565111198, 10564202857994065111393547880645251178272883989091662322926538117319878432736191255021584452078150595501973774866011810362628693221145487469693737829200383, 12280287372326889960058735723945388524941236194991220873019043205542308103155918129805263169248253576006353180937005508566535224983442257241572804641152426, 11925191918672244515278232269335187821495224324683091848920308746323029386207173462856629554668584177019719583318278759034034599496414911807326743929742783, 8681558174025541011736083260401681666724594308238702621814134214027616699233673968763037410024997130477047754948085180261248179935861957097734922118061060, 7421760901942600346273680662142416316666603470146232686148031074274579330925592316005490283863352596277971195286682092853049669158727791916914495886443866, 12718280316714974272565847994888010737621216266507899738540581152134126698856246587873904410718112658609463981997040301757808092029693908405279171541492496, 9732793095252434749963060917387723352208080051374214787045085885311319643865211928359465510544451603752403131693330866151499272294611118747328249752668719, 10649399380706413639949826640708205017558897015026736026675138633099374048709584849813036754038576754370070774972538785800540800838374686276814987660089591, 12750011730465910557781320358689897902639952697256697204764564985662185710378487944776963124799511133309854613386364374226869126900973627887741757877439032, 12282996816948857509581119405286122968975340682696788068186075073654989524887778043005913914778014003386618365244169755291655027778405089997623923617660325, 12839378613874614267798211852429412809886686352129932594919863726963711637066095978744474462446360106596073325914814819272840493160080521888215197533032513, 10358709104243600410703526277458148720338091943328799275800174743846532163567820635206792395936381788393969950256688671762889577767095914438338603340828338, 9873257080620858568674791652081627992486894026323344704211227067248308228317825180815820219421875743611936054896855875422768517776032850188833728733445595, 8389675923609696337548643228663299051342953983995801001983404754266919289694939761230472351442838514333250392809289832547868220650294832608120817507197763, 12078149509484809269046716364831436416980970210756313194588477537619003048810741511494726042112157310903539523731474341296485873311360608697015894580489054, 7488678661593562160422453904434268768963208540115661416280600748747276254619939578659884658047902409362123614585208647023568222682822898325778328923892846, 8425192873119881201693739950488712015964225578993290379844038460153438542121508219494330885704331074682903059856693784509382369914654805199321850478191379, 7219787071755769504741028253901520723929152174869957070907865648382767645551559422575424410436754505119473890369368642541097953665085290048105541796085768, 10746198877910720260524263236860964771121401427126816398500123210542632691353295114891914877713799283380939970385761923695789598662306574252512339627089709, 13384505673404409675098432005948426847068134987109295820384261979680517149908289762280996920650119209897911507972973134653728823245305600258864667775042166, 10184934147380994726277725404878733792549426789107970489721181902584272821826856092173445773413825777174016405315011562829723009379657508440746287556027050, 9036149919742427845553607017750340310891934553462811743667744640768457682553618073595375215873050933190876979564601427434559695276864234892042444722578401, 11120993541372778696648016938899308585826679016714679609717987112186356687538436347095526929168712319412079011439164159733117679703457078489227682906390096, 12882628689763515767395868921144432335501067230015238472256480668967186748576650562394447059544444037458764404953994439434118699732764231610231970343289459, 7442715826874554354676865519359627454386458623048765887946825913446256999256266429251533231782491753588534199928058986431130143819618656928017425423149707, 7964405287202080342179662020661779562856068295525295681267766448837747272082738774511397684272680611350344176536559910504497307034880553213338577000829961, 13322667051582098349132316757378868996178443762044835034512388114015267003931206644863203084096905707698939166744304343641974059995288500891884740532503520, 9448450516836465584579172385352690170202687742890888649721036046420421906507032304970513449813453161151428394490056694539374281209427721626460681088027772, 12961141973790693646691156903880982156147419270579958568305973226519539789202377359256833502160089584123902356302644272962954973582957791441532607926496651, 11266725033407389830497977257211492382543600146696809090150412437681893445916047063107041273224336331355419594538473158253848672050419367429131096129506716, 7597558620427593547939372473767189711509252476877664934679775714395474783561517822569461007241053021723045556559428211614014647660115725621411237423077988, 10316294475212487346106885988215875471579705441085550216908233994549578339387490009208995003610956133346153554171691485338184066361644380813110530224869877, 12690777770239154507675561681469310466474524463587482162804558792905776631956207061641209124089142658764702336075173799684560273010378680590200475825215277, 12274752319475565251628796391303423038062173448519820201337702763628555051772757898411224457527123964108991583185632929307036348135675927338395936653448833, 8132144911973512270251163410577017049199867010272325747192996369269983477503774176981216697140382895091971584663812393594201281094194000993995576485689712, 13233780203945330052199410805979805000669892078077480172109786919046480694241517292497339122944481584089835811933352494635588461682660304490481539636347027, 7475157845722070403095811259118578650977085938447921162867878620236647221023172828671738063756351143579516187603451375581267923480506119715994258586363326, 10938916359741770194742693878943465598380064558998134120220734369525050460666579927341107197147034801965604758816585350898856358067169777639990811234259319, 11514813772506059359799930426895381781838673160049019439384857476915466373956568819774350142159832354802997678783546907166310420424665931026901006380678556, 12296707733480650813853874287123257976593122304619349428073759479997302005956968461004077345551926146493731641370188726468778254341866912829531890091189152, 10489113621780242161096420088694940253852906622609454895548536724988220736621583256223111721152457977195012232072539001243468801981420036966505445855073042, 10369006273892428067763204259065944420375713190022072966517550953412204159094146435207551865489898427768948937000841756213514809185531413978425945060334768, 13264725271782237148366063449121483549408494918551886384844053229481201840098196192543597224761817286833769383233580809184283606115605173852587770214806099, 9662072757531234716824780272388992502986278211582481525837536429447395598455230637946272640956526395525744888972099409465561688265581112032526820039045666, 12044732083773310600992978633773096994802224481087382696032567022821473424910803080306846411825753489264000362188291376931778386440648549619490502826207040, 10608755788158669888045411794173293239577000191602616266433849093790037882284751041294411192317439153921890885554167037200293760895867295530715302127423425, 8483575995914325021515271538665073403337540875906750869792808676720420246575894209986593877934210300406486792380103635778773660751735005402629175071396325, 13286038972627727018318261823012406383508481055880524181384447338958396921098185416043363344335714146624191377819224876160297831124368415595159814934884986, 11473896849905633318466756638710166200502999913985514849812883993136304961722382120797040750086227540242485165730900733779087144282060320337923031442528110, 8708525386068400697309781194510844007087656899607737871548744513777975044033694737980625075923081399310547985970890568631790967768041805135044068578236398, 7894718919380593935170650018112763488507510920086526087048014676760553958737351377990135424850854276756598820798742231158604385827893682040080518521723178, 12266446141066400444611491690198230567188584154274393172102093955768568529185651701200559623270680130001455463322031820043190370582442311815007043349162708, 12649914684999681018231244277727979882828337551653036715049153040313968940892560377243908720365779938516959150329477969437369055145637849253019864244510671, 12710875287736060776630917666097331800459926369870826279524458245052218279480507791586841308021391228545713667229643553624446972742556689301011780664343583, 9333308488314126649339629664371723012014627332700436065661153266464992286962574969769991824982373053593428773089707810941666593346198677853791779836303861, 11442724383659467804578423920247692750091220654347400004704329800053274321719865569214773371127430973467655915153623436676948657103530575447885406270396615, 11035203009190565083146123603053403456035954778267372708482889269460180536322294846487651106794019582227986060653542317243912030794250698941514931037076213, 9301944566991165034014915702805440921705244389599424291348832345408938002136609153823859470690036980033237825423340421133281016208201150507271437530672684, 12994294972053640612032545797264458118633289076921659182286917217114018124767929657202819478367179158098565264955649933494701648198019517069336376592568103, 9305330463380544061573097743576872023126935689804417993565400052070453775302825889512890445470179394575247213488940461942931679236377564753428351493883870, 10243622989611100407239519241875791159993730562682321627585932476213506154594633708901797746010259485876166157006123538589950571616678583922110267874749147, 11405464221115459846586499351615089836262864822732296053699947528433721286644268489300504236557346063702684398610816088717744432442192094361416435377185153, 9846871184725811313256689540524805177861702919857096099095120938123181633576443785560633848944134220640613451483481597488676361699908009719508486175407602, 8552212542468855721702376276525178755103871854849589710035912304672106752020570818853718892682865930752705446060255314448169862495642705945884157941884558, 8225111166012248729226480978179677872617546742192983984900363342759678966029182354923767705044011358898335600020159190872157681922553822880098663924020743, 7482494570894490265743731969534606399668202045355500715548712924332439741699079808906110851200678596890365739112363959735481987908970193906786293941842409, 12083847566342191237233937406751890021383111340631111905912781970620224704228493269341428435613762965093560667232740937637923074246663253973813287812830920, 10594066261750332058974635701597775665367697493523345115606286486617690107385722162520167932024038121829580740292629484064009379186215223597790563879120601, 7247129890243357762054491825067135561265258621889569646027875402642825719631550299864958946306768856506937186358137043301761489401324506766135864468386891, 12460155883473959121464388638656632542941340285173809363321560201858660097897781551882361963725784812829139860625547877491354465485468006127597768496104487, 8059454935270798361515372056991160709341247254902102267653114103513902342196240022466556892300242417565049032323733357598998758630594366088218001248688225, 10204749175065440688138800547618307825374172507823677078496346370921336112848031949515041893661175734014640753684287975267475061777456422321518746981280661, 10490695413678853922448076447859895294642903449605336396487112600196528755193527582458444983515606825487055967634732278168883596915558770355277030757271430, 12612050711499777144961488863332098071227028907576137059959713190628722222929706016607238310395812656174942153242003738231358252385347078038899611656392118, 9170678761807120001761515107339842367839806040602783575862828102153584153826513012004339033122113368737188975571087962838875417696978408240619961522774765, 10067666479090800076639571170712154139610706422225051333851496276851891025065073065090254616738470844180858993232416206403456758717084477096437518103717755, 9715651803342736196528986269506763849952462520096339588897275031345871085666881932299008110239840498475566763584906863526126988148432197484258106693352630, 7099987069478807106863398413477700497558261261654601775280210573693653609893925144650769798555583854311799336865141480317618208120973081314544091929293092, 11465108303309074079777846301227782791282078042151712595108904140925107541932354637692875275007168916110323407725532393780240790866886065208154529913469112, 9904930059818148806140809486390460548930375579315967308493382907027112467243726454658804300784453936614364834858685496702951671926542647423118794523386987, 9478499159325476786481075519278386565429264287057628046436916497851338820120913790982421023516528639145595469547354401810074092803440912161233790996146931, 11252239218061057841296940171637150186296793820862966369127309104567931517566534900440627331201546295320085241123825371771858199976495926952914973191759032, 12515793901191909375110203870037965305459220013298857734328739709097295976618871177393856526769327849137800025647848944501259149431419355306996442310648519, 10376413529767157376342804044816322715388450350485864166674671039397457381872434674751592873301617805011000242393974252800002987877637297538276774891678884, 13029944477419558002176957562029876914635936318723837586422380574186145375888988275077921941317412498738339399505836732583749028614401817563579472260562640, 9128973335410036432600056443901535952009382709835907375093618651758378722544053344494652437039441540313776715819428837874459601980087191955184492028389857, 12593082072038783271498516772963445124041185525938380308324990765558831149181638485094164505896832485761388658651338614637165343461595947218579731812372528, 11735077618674013612958820277328911531712056625782436487029546732268919017259298703917806002101583054245699020720687772508773715281974339096924201583660574, 7728784794272114065122251432569539367347669308435288683752010693247072719737935809354007319392196737344427297861905440100229532645519580981409977875477389, 7428247123612091434393868203105301144353738609125850521562292641267220723343764024923540679070061995033156020359443332402625848142710250478784927289822628, 7175631974722981646128907593630467512452568751413750660744598769656813582511577653449757709452871141988712102890994785889561778896828321219141776092936568, 11712729924217277711865941037353225655482144725132027647664241337404336587970198887018281992403024816325689402771466343696962527091043127373644051644499287, 11224922155881774876594420721948586946393014125972323121120123075745041422974431140306033119082716867866743249075099557462815732359026328549852192450607741, 7231424949131490246727570429582622002892820539158734542873543907718273873792106728737316038356516071485540926921685587333249754995404998273036282309214062, 12114026385457326314841814285471275326758879303751936710201161387722392263618638519770458330763258760723127567043511482427579569131629531264626128510587534, 11825196773678792668072747036231219052787265543710658792398946607772166234189107016805561245838528067132361784466616653131913402382816329156230169174829506, 8245008652627109779307969764316435426741245787633187676521341079921989988009890995149923524480201528984525419037000932803530272348039818862385946189208378, 11416872024745001893455670680441271032680429820629322910942279643546706696238412593818592206887249291314614269393564833810186179898019659753291792503054054, 9508103517738598162567515490140029522340899875468997709060843634300311903124525372677517883001094310168739759480427719014989087786724662462104776498860492, 12591666699340031784535689393492723021027581380950031341932492829215243597157543657985259006753398140540174561527921998646985165856089250965827305580428252, 10562979121148553681972944438801187843886610211327188638714789615417095614977184159083271923313990107523324317881077372619688918935360186670705758515614034, 9178837496809599045862745747101563821807913158145203001105088869347588283288513025992623864883370514373305323099410924866631466342279879940019297435884676, 11956643437497544605884776011280542209055203080772831562110377479125001713625733896960800643053248723958226539435343822578679360319361571672850494732543203, 12184355754385604285228006766001493884035295482237476094611620279035873563440114270062886517280622409270838457351277493919048715221447196547677444490691428, 7878417430173149671564700676946725257620857391247396621737200901555751594355240811350122547844039571130689835702513106338478637248022086359181651252812508, 13312813158209676681570719426324572903483261973326824942607834418275619060627332751222240122553605976861705748558407537736583816980351762638561898934449301, 11600762468969696953863595008447206152295524364501612305105479840520264188050378119439443203571526874409556122686633577611416718983525459649817246832984255, 7250768579343183955676652663488588363560421183517593418767904737219889802958466575474882474424337833305409871428784423676588437843576573576224901442209548, 10979128067448567633752026435877176848974411275103795791726934781479688433453345740452608682907863444272819558497652231413335004661278269156475578086255981, 7436255105275100420460511416898153049291713468966622217617088662643222540983734860154725001150551006725308043007333856948772534422998385295038520876220598, 10027187252357663308571702526178408111815034757583877140083937931534908669521303896957717717513954786265692860219593930801897757979055340414529113917679988, 8336020549751622981511233584077476561842805462625479276723362357288093796941615289966840970742892124083139760416284132806511693877286341727360200395852231, 13054661861061728198679569261116855487163066351871684551433842964991655043382533802861526981328329680081967902271755936958553327473926624447437145495116253, 8634658049427271062042590042368462997697805854519689956002345693547396306577472725817611605315158187595693984537899870869612598389538231647705566671059418, 8218859159159519121578038598020467460281694222407262298629402803476144685651239390515718883553322566586506442021743499760039042307986552346745440499993959, 11801501626217591270438739508546003475402288406666108366097163000458374631971333879472147966648996405509001738318767513711820489138111353353525840194189509, 8605785955844728062986856030603676194251525921293060970100816477468100045047992796026633064050929577214302592581667869654622678073625124202832059251400297, 10117229838996011301883144129611091204008442240435959965329058887856264697365669296641014806682180111992415128091448183791184716776608499705464667586037677, 12321041828110011457615402015754690522658254207385169331221314421844640651871934686472644492199794918256175508918654693602027901572746319106401436817684747, 11246283725752645417309801718187628770004918555044609288449505048463338475720605453424713083126772025117549401384876556341543977652136472148796626328425414, 12831414075418083029159814264534637503514734115414213445265644481423314888168579038364434837209331748540081856777262291691395427444632482037010325077486944, 9595966467704475383634944984603715362413078383908189132703471957517990025096255540029920933892252363222342509620123169951479165959399421494839281662981676, 8210490200722254391151906559848796059453183915837396987244211442829943382005628703724695234417959734186563078140839179155844980203792133728316128013516459, 6772737541220477638159499252508190255552737394375891863077243378899267608924108126989158371039643311108142669239413004969376222683419863566922553604258368, 10184023085368966148882996065749308368116427013211338160561701288471509497238447433784802152303568669892114745065012908072175121692281777812676413937295697, 11127358062138750248053934470898107749742646904916348813766599458316583175418861124570116362190130205034453819816078608295458976718118630886200466488100967, 11529460248614240296791427195154646599246525154206478576803758495983973025866809998957157546756808200578349799003627023322509515227283481790254725268885477, 12505621444657702877876739396548470369230403642305039653182152126534701367345992713776844611661039509728232070774873193447802782288920587303349560570712431, 12337656523046134837796036105124507500143381364164038917449860382700442342458628489308556317737273024038630915766720966264442092397495182424426360640336865, 10096911411989343401267191377928312934098560942232245075079600048783991448108424147699470190548394862446086923835310653725309152450997002711842610348743685, 7536528374946626787967288767876941313511898500716930016389502139719460486496704526601531264032647710884356580156855892377130570194635815454209797883778712, 11714773544931520071330775066817901860521542882972499602179556555429751439737889316284829231302244442396757773980879353474860837811614915458624808969806765, 12675953244323030707184386243568044000487235537178395012260497075543046976750897231903498878822254142182428659335451969469787713135399727308864597104444945, 8426855509697546440323016770896042150174290751983772023561120617087320182091222636357237548239185014642742164372015268862802199403827427912103379437899585, 7358031133410933718618323927731196031130633291023516275633596111347201585917729679362334066818111716891194152906469009157548249693007418787373617425702675, 6857509265718723627041261393029482099210922361466451711589121319063064231528784098105686582153577949069545474457975771137471905216089431588759498103552581, 11041975321164286355214218915135068262323251092906754493652880931822678298134179716931882673819543970319701909064440755540762201428571429583633706970143396, 6913386380903477835454690385930585000117422493822910396076262281782848662925197567392854391120069101351367334101730451462588374025250973256929569334364836, 12992425255590926782042858261897315381688346050527924628935396615272259508489461407871947957460459424172482142763610270875313779577319565954247824077745661, 11038447624549545775541007087817446204683054050075818424154602297279529534041124812421663731970648463874362136420108305010061276192575929564521964904227776, 10672541722819899103483728733076765816908124918856132730612730889182919902422018924804647626496958937605714703384215978820876132733110072193233069231189815, 7448922368464509925970050780962230079654847870268825683258611007545247803919150658973723771159476901487418708315752451400549902833407581146959902018328417, 13123685873482264099061779728220668251370698878627857386253702725357658914679172121473922993891533392463294057656858575004478432263422702544529977587941261]
n = 58113574203067314600162910771848744432179168354040678920098167335472534222998261639291145191568159464990603689062679467360303185717662426122140998218656632568172511390111887830539687208220100574329903748617343193392646019854280519859403817579746765861359633174218846216669659258251676438195667516224684805919
c = 56754194307199340085459028397027924827853574000671575387226403396873568994756738512141122143372650573201079937375922460851170745485734799044781029943783218210457587599666501326645229924138230588050782907693019958930006807017898115655426823272342984109999519420817119999272583495848119171867835187241510764427

解法

parinad関数の処理を言い換えると、入力の全てのビットのXORを計算することと同じになっています。 XORは計算する順序を入れ替えても結果が変わらないので以下の式が成り立ちます。

 \begin{align}
\mathrm{parinad} \! \left( x \oplus y \right) &= \mathrm{parinad} \! \left( x \right) \oplus \mathrm{parinad} \! \left( y \right)
\end{align}

よって、vinad関数では各ビットごとに \mathrm{parinad} \! \left( R _ i \right)  \mathrm{parinad} \! \left( x \right) をXORしていることになり、 R _ i が固定であれば x を変化させても2通りの結果しかないことになります。 したがって、vinad関数を使用して計算している p, e はその2通りの結果に含まれます。

 p の候補のうち n を割り切るものを取り出せば p の値が分かります。  e の候補に対して以下の式で平文 m を計算したときに、フラグの形式に合うものを取り出せばフラグが分かります。

 \begin{align}
q &= \frac{n}{p} \\
\phi \! \left( n \right) &= \left( p - 1 \right) \left( q - 1 \right) \\
d &\equiv e^ {-1} \pmod { \phi \! \left( n \right) } \\
m &= \left( c^ d - \sum R _ i \right) \bmod n
\end{align}
#!/usr/bin/env python3

from Crypto.Util.number import inverse, long_to_bytes
from ast import literal_eval


with open('output.txt', 'r') as f:
    output = f.read()
R, n, c = [literal_eval(line.split(' = ')[-1]) for line in output.splitlines()]


def parinad(n):
    return bin(n)[2:].count('1') % 2

def vinad(x, R):
    return int(''.join(str(parinad(x ^ r)) for r in R), 2)


p_list = [vinad(r, R) for r in [0, 1]]
[p] = [p for p in p_list if n % p == 0]
q = n // p
phi = (p - 1) * (q - 1)

e_list = p_list
for e in e_list:
    try:
        d = inverse(e, phi)
    except ValueError:
        continue
    m = (pow(c, d, n) - sum(R)) % n
    flag = long_to_bytes(m)
    if flag.startswith(b'CCTF{'):
        print(flag)
CCTF{s0lV1n9_4_Syst3m_0f_L1n3Ar_3qUaTi0n5_0vEr_7H3_F!3lD_F(2)!}

難易度Getting Thereの問題についてのWriteup

[Getting There] ASIS Primes (40 solves)

ASIS Primes is a cryptography challenge requiring primes with printable, meaningful bytes; can you generate such primes effectively?

nc 91.107.252.0 13737

Note: Please re-re-download the attachment.

問題の概要

この問題では以下のファイルが配布されています。

  • 問題サーバで動かしているPythonプログラム (ASIS_Primes.py)

この問題では最初にビット数 \mathrm{nbit} = 512 の素数 p, q が生成され、 e = 65537 としています。

この問題では問題サーバに接続して以下の操作をすることができます。

  • 平文 m に対する暗号文 c の計算( \oplus はXORを表しています)
 \begin{align}
c &= m^ {e \oplus 1} \bmod p q
\end{align}
  •  p, q の値の設定

 p, q の値を設定するには以下の条件を満たす必要があります。

  •  p, q が素数であること
  •  p, q をバイト列に直したときにそれぞれ特定のデータで始まること
    •  p : CCTF{7H!S_iZ_th3_f1RSt_pRim3__P_f0R_oUr_ \mathrm{nbit} の値、-bit_m0DulU5_、ランダムな文字列の4つの文字列を連結したデータ
    •  q : CCTF{7H!S_iZ_th3_s3c0Nd_pRim3_Q_f0R_oUr_ \mathrm{nbit} の値、-bit_m0DulU5_、ランダムな文字列の4つの文字列を連結したデータ
  •  p, q をバイト列に直したときにそれぞれ}で終わること
  •  p, q をバイト列に直したときに英数字と!_{-}の記号からなる文字列として解釈できること
  •  9 p q のビット数が 2 \mathrm{nbit} であること

 p, q の値の設定中に例外が発生すると、 \mathrm{nbit} の値が 1 増やされます。

  • ASIS_Primes.py
#!/usr/bin/env python3

import sys
from Crypto.Util.number import *
from random import randint
import string
from flag import flag

def die(*args):
    pr(*args)
    quit()
    
def pr(*args):
    s = " ".join(map(str, args))
    sys.stdout.write(s + "\n")
    sys.stdout.flush()
    
def sc():
    return sys.stdin.buffer.readline()

def is_valid(msg):
    msg, charset = msg.decode(), string.printable[:63] + '_{-}'
    return all(_ in charset for _ in msg)

def rand_str(l):
    charset = string.printable[:63] + '_'
    return ''.join([charset[randint(0, 63)] for _ in range(l)])

def main():
    border = "┃"
    pr(        "┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓")
    pr(border, ".:::       Welcome to the ASIS Primes cryptography task!      ::.", border)
    pr(border, ".: Your mission is to find flag by analyzing the crypto-system :.", border)
    pr(        "┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛")
    global flag
    nbit = 512
    p, q = [getPrime(nbit) for _ in range(2)]
    e = 65537
    while True:
        pr(f"{border} Options: \n{border}\t[E]ncrypted the flag! \n{border}\t[S]ubmit primes! \n{border}\t[Q]uit")
        ans = sc().decode().strip().lower()
        if ans == 'e':
            m = bytes_to_long(flag)
            c = pow(m, e ^ 1, p * q)
            pr(f'{c = }')
        elif ans == 's':
            pinit = f'CCTF{{7H!S_iZ_th3_f1RSt_pRim3__P_f0R_oUr_{nbit}-bit_m0DulU5_{rand_str(randint(5, 40))}'.encode()
            qinit = f'CCTF{{7H!S_iZ_th3_s3c0Nd_pRim3_Q_f0R_oUr_{nbit}-bit_m0DulU5_{rand_str(randint(5, 40))}'.encode()
            pr(border, f'the condition for the first  prime is: {pinit}')
            pr(border, f'the condition for the second prime is: {qinit}')
            pr(border, f'Please submit the primes p, q: ')
            inp = sc().decode().strip()
            try:
                _p, _q = [int(_) for _ in inp.split(',')]
                _pbytes, _qbytes = [long_to_bytes(_) for _ in (_p, _q)]
                if (
                    isPrime(_p) and isPrime(_q) 
                    and _pbytes.startswith(pinit) and _qbytes.startswith(qinit) 
                    and _pbytes.endswith(b'}') and _qbytes.endswith(b'}') 
                    and is_valid(_pbytes) and is_valid(_qbytes)
                    and (9 * _p * _q).bit_length() == 2 * nbit
                    ):
                        p, q = _p, _q
            except:
                pr(border, f'The input you provided is not valid! Try again!!')
                nbit += 1
        elif ans == 'q':
            die(border, "Quitting...")
        else:
            die(border, "Bye...")

if __name__ == '__main__':
    main()
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃ .:::       Welcome to the ASIS Primes cryptography task!      ::. ┃
┃ .: Your mission is to find flag by analyzing the crypto-system :. ┃
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
┃ Options: 
┃       [E]ncrypted the flag! 
┃       [S]ubmit primes! 
┃       [Q]uit
e
c = 74822262234426191074466862962126538517758404290764762577640730187349199015797648151121986330881521128854866198488071764788679445072216118311846362296538821593123634632637118766749349154660193756690867906386045390198018307240463901595090018243315249051491473160109332033796544634544073571233979904453615366582
┃ Options: 
┃       [E]ncrypted the flag! 
┃       [S]ubmit primes! 
┃       [Q]uit
s
┃ the condition for the first  prime is: b'CCTF{7H!S_iZ_th3_f1RSt_pRim3__P_f0R_oUr_512-bit_m0DulU5_ukIicPQrQhA2fuYIZB25Ow0bfXHWb1bKVGZmKcP'
┃ the condition for the second prime is: b'CCTF{7H!S_iZ_th3_s3c0Nd_pRim3_Q_f0R_oUr_512-bit_m0DulU5_SyyVWXft0pdj5QZi5oXL4O4HE'
┃ Please submit the primes p, q: 
11963059730700108865443726651161811666282804157537077276855433530014571783370600082830224998484238887497709121129426967560011457766417356162546546016983889,7549929014402650186066229410776169769137882626441932096823963997735844029839664328905504336640703860184878974835782334252470330938198661031639552185291357
┃ Options: 
┃       [E]ncrypted the flag! 
┃       [S]ubmit primes! 
┃       [Q]uit

解法

 \mathrm{nbit} の初期値である 512 では、ビット数が少なすぎて条件を満たす p, q を生成することができないです。 そこで、2つの整数として読み込ませることができないデータを入力することで例外を発生させて、 \mathrm{nbit} の値を増やします。  \mathrm{nbit} の値が十分に大きければ、素数であること以外の p, q の条件を満たす整数を生成して、その中に素数であるものがあればそれを取り出して使用します。

 p, q を設定することができたら、暗号文 c を取得します。  c の値を取得したら、 p, q をそれぞれ法とした c  e \oplus 1 乗根 m _ p, m _ q nth_rootを使用して全て求めます。 全ての m _ p, m _ q に対して m \equiv m _ p \pmod p, m \equiv m _ q \pmod q を満たす m を中国の剰余定理により求めて、 m をバイト列に直したときにCCTF{で始まるものを見つければフラグが得られます。

#!/usr/bin/env sage

from pwn import remote
from Crypto.Util.number import bytes_to_long, long_to_bytes
import string
import itertools


# host = '91.107.133.165'
host = 'localhost'
port = 13737


def select_word(b, nl, nw):
    return b.splitlines()[nl].split(b' ')[nw]


def generate_prime(pinit, qinit, nbit):
    if (2 * nbit) % 8 != 0:
        return None, None
    byte_num = (2 * nbit) // 8
    generate_byte_num = byte_num - (len(pinit) + len(qinit) + 2)
    if generate_byte_num < 0:
        return None, None
    
    p_byte_num = generate_byte_num // 2
    q_byte_num = generate_byte_num - p_byte_num
    chr_list = (string.printable[:63] + '_{-}').encode()
    
    for i in map(bytes, itertools.product(chr_list, repeat=p_byte_num)):
        p = bytes_to_long(pinit + i + b'}')
        if is_prime(p):
            break
    else:
        return None, None
    
    for i in map(bytes, itertools.product(chr_list, repeat=q_byte_num)):
        q = bytes_to_long(qinit + i + b'}')
        if is_prime(q):
            break
    else:
        return None, None
    
    return p, q


with remote(host, port) as conn:
    conn.recvuntil(b'[Q]uit\n')
    
    while True:
        conn.sendline(b'S')
        data = conn.recvuntil(b'Please submit the primes p, q: \n')
        pinit = select_word(data, 0, -1).strip(b"b''")
        qinit = select_word(data, 1, -1).strip(b"b''")
        nbit = int(pinit.removeprefix(b'CCTF{7H!S_iZ_th3_f1RSt_pRim3__P_f0R_oUr_').split(b'-')[0])
        
        p, q = generate_prime(pinit, qinit, nbit)
        if p is not None and q is not None:
            break
        conn.sendline(b'invalid_data')
        conn.recvuntil(b'[Q]uit\n')
    
    conn.sendline(f'{p}, {q}'.encode())
    conn.recvuntil(b'[Q]uit\n')
    conn.sendline(b'E')
    data = conn.recvuntil(b'[Q]uit\n')
    c = int(select_word(data, 0, -1))

print(f'{pinit = }')
print(f'{qinit = }')
print(f'{p = }')
print(f'{q = }')
print(f'{c = }')

e = 65537
m_list = []
for r in [p, q]:
    mr = mod(c, r).nth_root(e ^^ 1, all=True)
    m_list.append(mr)
for i in itertools.product(*m_list):
    m = crt(list(map(Integer, i)), [p, q])
    flag = long_to_bytes(int(m))
    if flag.startswith(b'CCTF{'):
        print(flag)
$ ./solve.sage
[+] Opening connection to localhost on port 13737: Done
[*] Closed connection to localhost port 13737
pinit = b'CCTF{7H!S_iZ_th3_f1RSt_pRim3__P_f0R_oUr_540-bit_m0DulU5_FscMK'
qinit = b'CCTF{7H!S_iZ_th3_s3c0Nd_pRim3_Q_f0R_oUr_540-bit_m0DulU5_YGeeqm7'
p = 230873458602212695519694839787849317581235632209002405159227304383379038227223807201273260430465259671803375718870227700934451747988766713304264547043862720637
q = 3873413883636380470676152581206142176512996347529177140262498299525330268224010010362638904884474150949466955476806153042037800649789692878084456335800810808875692157
c = 886508573135770930839562686940653133606619417910143468409822653288442039962073397872529497290752267153824029623547207374852457813913269405497202283628759357487528319157210194004153287405443992911015224098238738313125053132080928941935403564642416875629865660793024288828331668872321674180746065196389704561741955424215302259
b'CCTF{3AzY_RSA_cH4l13n9E_!n_ASIS_CTF!!}'
CCTF{3AzY_RSA_cH4l13n9E_!n_ASIS_CTF!!}

[Getting There] Ikkyu San (31 solves)

Ikkyu San, a sage child, developed a unique crypto-system that helps young CTF players identify and choose talented individuals.

nc 91.107.252.0 37773

問題の概要

この問題では以下のファイルが配布されています。

  • 問題サーバで動かしているSageMathプログラム (Ikkyu_san.sage)

この問題では最初にランダムな素数 p  0  \lt a \lt p, 0  \lt b \lt p を満たすランダムな整数 a, b が生成されます。 そして y^ 2 \equiv x^ 3 + a x + b \pmod p という式で定義される楕円曲線を E として、 E のランダムな点 G = \left( G _ x, G _ y \right), H = \left( H _ x, H _ y \right) が生成されます。

この問題では問題サーバに接続して以下の操作をすることができます。

  • 楕円曲線 E 上の点 P = \left( P _ x, P _ y \right) の入力と、 P _ x G + P _ y H + G _ x P の計算
  • 楕円曲線 E 上のランダムな点の生成
  • 平文を m としたときの m G _ x H _ y の計算

  • Ikkyu_san.sage

#!/usr/bin/env sage

from Crypto.Util.number import *
from time import *
from flag import flag

def die(*args):
    pr(*args)
    quit()
    
def pr(*args):
    s = " ".join(map(str, args))
    sys.stdout.write(s + "\n")
    sys.stdout.flush()
    
def sc(): 
    return sys.stdin.buffer.readline()

def Ikkyu(nbit):
    p = getPrime(nbit)
    while True:
        a, b = [randint(1, p - 1) for _ in range(2)]
        E = EllipticCurve(GF(p), [a, b])
        G, H = [E.random_point() for _ in range(2)]
        try:
            I = E.lift_x(1)
        except:
            if legendre_symbol(b - a - 1, p) < 0:
                return p, E, G, H

def fongi(G, H, P):
    try:
        xG, xP, yP = G.xy()[0], P.xy()[0], P.xy()[1]
    except:
        xP = 1337
    return int(xP) * G + int(yP) * H + int(xG) * P

def main():
    border = "┃"
    pr(        "┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓")
    pr(border, "Welcome to the Ikkyu-san challenge!! Your mission is to find the  ", border)
    pr(border, "flag with given information, have fun and good luck :)            ", border)
    pr(        "┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛")
    nbit = 256
    pr(border, f'Generating parameters, please wait... ')
    p, E, G, H = Ikkyu(nbit)
    F = GF(p)
    while True:
        pr(f"{border} Options: \n{border}\t[E]ncrypted flag!\n{border}\t[R]andom point\n{border}\t[G]et Ikkyu-san point!\n{border}\t[Q]uit")
        ans = sc().decode().strip().lower()
        if ans == 'g':
            pr(border, f"Please provide your desired point `P` on elliptic curve E like x, y: ")
            xy = sc().decode()
            try:
                x, y = [F(int(_)) for _ in xy.split(',')]
                P = E(x, y)
            except:
                pr(border, f"The input you provided is not valid!")
                P = E.random_point()
            pr(border, f'{fongi(G, H, P) = }')
        elif ans == 'r':
            pr(border, f'{E.random_point() = }')
        elif ans == 'e':
            m = bytes_to_long(flag)
            assert m < p
            pr(border, f'{m * G.xy()[0] * H.xy()[1] = }')
        elif ans == 'q':
            die(border, "Quitting...")
        else:
            die(border, "Bye...")

if __name__ == '__main__':
    main()
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃ Welcome to the Ikkyu-san challenge!! Your mission is to find the   ┃
┃ flag with given information, have fun and good luck :)             ┃
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
┃ Generating parameters, please wait... 
┃ Options: 
┃       [E]ncrypted flag!
┃       [R]andom point
┃       [G]et Ikkyu-san point!
┃       [Q]uit
e
┃ m * G.xy()[_sage_const_0 ] * H.xy()[_sage_const_1 ] = 57456461572037253029979680416623873067726535291117504835219884044369659724729
┃ Options: 
┃       [E]ncrypted flag!
┃       [R]andom point
┃       [G]et Ikkyu-san point!
┃       [Q]uit
r
┃ E.random_point() = (16676741416250147736983815434538406027250725398271818891474621963832205599355 : 32010947005722996185967494859992379428306574926079434424798286392823691606265 : 1)
┃ Options: 
┃       [E]ncrypted flag!
┃       [R]andom point
┃       [G]et Ikkyu-san point!
┃       [Q]uit
g
┃ Please provide your desired point `P` on elliptic curve E like x, y: 
16676741416250147736983815434538406027250725398271818891474621963832205599355,32010947005722996185967494859992379428306574926079434424798286392823691606265
┃ fongi(G, H, P) = (11505710594034893243854168408620823645637983269160539769180600949816213271334 : 59154014582093818614405655037691558845220383671882316126650630548851458477245 : 1)
┃ Options: 
┃       [E]ncrypted flag!
┃       [R]andom point
┃       [G]et Ikkyu-san point!
┃       [Q]uit

解法

まず楕円曲線 E のパラメータ p, a, b を求めるために、楕円曲線の点をいくつか取得します。  y^ 2 \equiv x^ 3 + a x + b \pmod p を変形すると、 y^ 2 - x^ 3 \equiv a x + b \pmod p が成り立ちます。 2つの点に対してこの関係式の差を取ると、以下のようになります。

 \begin{align}
\left( y _ i^ 2 - x _ i^ 3 \right) - \left( y _ j^ 2 - x _ j^ 3 \right) &\equiv \left( a x _ i + b \right) - \left( a x _ j + b \right) \\
&\equiv a \left( x _ i - x _ j \right) \pmod p
\end{align}

さらにこの関係式を2つ使用してさらに式変形すると以下のようになります。

 \begin{align}
&\phantom{\equiv {}} \left( \left( y _ i^ 2 - x _ i^ 3 \right) - \left( y _ j^ 2 - x _ j^ 3 \right) \right) \left( x _ i - x _ k \right) - \left( \left( y _ i^ 2 - x _ i^ 3 \right) - \left( y _ k^ 2 - x _ k^ 3 \right) \right) \left( x _ i - x _ j \right) \\
&\equiv a \left( x _ i - x _ j \right) \left( x _ i - x _ k \right) - a \left( x _ i - x _ k \right) \left( x _ i - x _ j \right) \\
&\equiv 0 \pmod p
\end{align}

この式は p で割った余りが 0 なので、 p の倍数になっています。 この式を複数計算して最大公約数を求めると p が求まります。  p が求まれば、 a を以下のようにして計算することができます。

 \begin{align}
\left( y _ i^ 2 - x _ i^ 3 \right) - \left( y _ j^ 2 - x _ j^ 3 \right) &\equiv a \left( x _ i - x _ j \right) \\
a &\equiv \left( \left( y _ i^ 2 - x _ i^ 3 \right) - \left( y _ j^ 2 - x _ j^ 3 \right) \right) \left( x _ i - x _ j \right)^ {-1} \pmod p
\end{align}

 b についても以下のようにして計算できます。

 \begin{align}
y^ 2 &\equiv x^ 3 + a x + b \\
b &\equiv y^ 2 - x^ 3 - a x \pmod p
\end{align}

楕円曲線 E のパラメータが求まったら、 E の位数 o を計算します。 また、取得した楕円曲線の点の一つを P とします。

適当な3つの整数 r _ 1, r _ 2, r _ 3 に対して P _ i = r _ i P を計算して、 Q _ i = P _ {i, x} G + P _ {i, y} H + G _ x P _ i の値を取得します。  R _ {i, j} = r _ i Q _ j - r _ j Q _ i とすると以下のようになり、 P についての項を消すことができます。

 \begin{align}
R _ {i, j} &= r _ i Q _ j - r _ j Q _ i \\
&= r _ i \left( P _ {j, x} G + P _ {j, y} H + G _ x P _ j \right) - r _ j \left( P _ {i, x} G + P _ {i, y} H + G _ x P _ i \right) \\
&= r _ i \left( P _ {j, x} G + P _ {j, y} H + G _ x r _ j P \right) - r _ j \left( P _ {i, x} G + P _ {i, y} H + G _ x r _ i P \right) \\
&= \left( r _ i P _ {j, x} G + r _ i P _ {j, y} H + r _ i r _ j G _ x P \right) - \left( r _ j P _ {i, x} G + r _ j P _ {i, y} H + r _ j r _ i G _ x P \right) \\
&= \left( r _ i P _ {j, x} - r _ j P _ {i, x} \right) G + \left( r _ i P _ {j, y} - r _ j P _ {i, y} \right) H
\end{align}

 g _ {i, j} = r _ i P _ {j, x} - r _ j P _ {i, x}, h _ {i, j} = r _ i P _ {j, y} - r _ j P _ {i, y} とすると R _ {i, j} = g _ {i, j} G + h _ {i, j} H と表せます。 さらに、 h _ {i, k} R _ {i, j} - h _ {i, j} R _ {i, k} を計算すると、以下のように H についての項を消すことができ、 G について解くことができます。

 \begin{align}
h _ {i, k} R _ {i, j} - h _ {i, j} R _ {i, k} &= h _ {i, k} \left( g _ {i, j} G + h _ {i, j} H \right) - h _ {i, j} \left( g _ {i, k} G + h _ {i, k} H \right) \\
h _ {i, k} R _ {i, j} - h _ {i, j} R _ {i, k} &= \left( h _ {i, k} g _ {i, j} - h _ {i, j} g _ {i, k} \right) G \\
G &= \left( h _ {i, k} g _ {i, j} - h _ {i, j} g _ {i, k} \right)^ {-1} \left( h _ {i, k} R _ {i, j} - h _ {i, j} R _ {i, k} \right)
\end{align}

ここで、 \left( h _ {i, k} g _ {i, j} - h _ {i, j} g _ {i, k} \right)^ {-1} は法 o に関する逆元を表しています。  G が求まれば、 H を以下のようにして計算することができます*3

 \begin{align}
R _ {i, j} &= g _ {i, j} G + h _ {i, j} H \\
h _ {i, j} H &= R _ {i, j} - g _ {i, j} G \\
H &= h _ {i, j}^ {-1} \left( R _ {i, j} - g _ {i, j} G \right)
\end{align}

 G, H が求まれば、暗号文 c = m G _ x H _ y \bmod p から以下のようにして平文 m を計算することができ、フラグを取得することができます。

 \begin{align}
c &\equiv m G _ x H _ y \\
m &\equiv c \left( G _ x H _ y \right)^ {-1} \pmod p
\end{align}
#!/usr/bin/env sage

from pwn import remote
from Crypto.Util.number import long_to_bytes


# host = '91.107.132.34'
host = 'localhost'
port = 37773


def select_word(b, nl, nw):
    return b.splitlines()[nl].split(b' ')[nw]


while True:
    with remote(host, port) as conn:
        conn.recvuntil(b'[Q]uit\n')
        conn.sendline(b'E')
        data = conn.recvuntil(b'[Q]uit\n')
        c = int(select_word(data, 0, -1))
        
        point_list = []
        for _ in range(4):
            conn.sendline(b'R')
            data = conn.recvuntil(b'[Q]uit\n')
            x, y, z = map(int, data.splitlines()[0].strip('┃ E.random_point() = ()'.encode()).split(b' : '))
            point_list.append((x, y))
        
        x0, y0 = point_list[0]
        l1 = [((y ^ 2 - x ^ 3) - (y0 ^ 2 - x0 ^ 3), x - x0) for x, y in point_list[1:]]
        i0, j0 = l1[0]
        nbit = 256
        [p] = [p for p, _ in factor(gcd(i0 * j - i * j0 for i, j in l1[1:])) if p.nbits() == nbit]
        a = i0 * inverse_mod(j0, p) % p
        b = (y0 ^ 2 - x0 ^ 3 - a * x0) % p
        E = EllipticCurve(GF(p), [a, b])
        o = E.cardinality()
        P0 = E(x0, y0)
        print(f'{point_list = }')
        print(f'{p = }')
        print(f'{a = }')
        print(f'{b = }')
        
        r_list = [1, 2, 3]
        P_list = [r * P0 for r in r_list]
        Q_list = []
        for P in P_list:
            conn.sendline(b'G')
            conn.recvuntil(b'Please provide your desired point `P` on elliptic curve E like x, y: \n')
            conn.sendline(f'{P.x()}, {P.y()}'.encode())
            data = conn.recvuntil(b'[Q]uit\n')
            x, y, z = map(int, data.splitlines()[0].strip('┃ fongi(G, H, P) = ()'.encode()).split(b' : '))
            Q_list.append(E(x, y))
        print(f'{Q_list = }')
        
        r1, r2, r3 = r_list
        P1, P2, P3 = P_list
        Q1, Q2, Q3 = Q_list
        R12 = r1 * Q2 - r2 * Q1
        R13 = r1 * Q3 - r3 * Q1
        (P1x, P1y), (P2x, P2y), (P3x, P3y) = [map(Integer, P) for P in [P1.xy(), P2.xy(), P3.xy()]]
        g12, g13, h12, h13  = r1 * P2x - r2 * P1x, r1 * P3x - r3 * P1x, r1 * P2y - r2 * P1y, r1 * P3y - r3 * P1y
        try:
            G = (h13 * R12 - h12 * R13) * inverse_mod(h13 * g12 - h12 * g13, o)
            H = (R12 - g12 * G) * inverse_mod(h12, o)
        except ZeroDivisionError:
            continue
        m = c / (G.x() * H.y())
        print(long_to_bytes(int(m)))
        break
$ ./solve.sage
[+] Opening connection to localhost on port 37773: Done
point_list = [(69522706375172429157691890653220939073471972009146196108880358862947145332829, 48066269923253231352282913028013158440041114330856263096120461463647226868084), (49195359448514217578884813783456841256657773226477720666730207708232422061718, 24544082450233094333353749858594049375651970202993040958866342568584516298504), (79278021082343360052876436069209502965911260160910602199441469585581040262248, 40049953824850745013641915130551444710242597505912790076758892869570114609394), (57518613214238672241707834549857554878110409000049659722005202833484817532169, 75207944553594358724076714058189642224738677212045638003029614473595079758165)]
p = 85415579459362954395743490462403791702501289310744617044019253519143481676283
a = 75598781352393456866351899353168436274821365526822994753017122053261548560503
b = 54773557132865142610186676745256883836922173550282110459095792318316574480918
Q_list = [(74240078639865422587206796864619301996118922957520101763041306663109806859196 : 32071153004552971786964743463709052222919214776913238372709677597687841148649 : 1), (45154361401673930399002914269653915642087043946018840083843126519950959482140 : 49864962718213412008146827807273495224906564506862258547480045821000006127201 : 1), (18322091396946489342922552847440919214794642167622504804656184991570132375604 : 36516034727689553598578204308241605539513511656605590226676168264581556230570 : 1)]
[*] Closed connection to localhost port 37773
[+] Opening connection to localhost on port 37773: Done
point_list = [(50952285846834664942074512738037958314903790424502868278521269842061198440767, 60435647031964201750208847612873801112841847104348242687346761307893199308132), (46069742682533081272083290272248052569961644533717522433451855685472249592458, 49086054635665272051674644239948141118761566677318961688532023716500742806275), (55463341381922115042451543876997559177952306419155292122187032487433541572004, 22255508039961348344062301372262188239973472639859135008412691749379892050938), (15117702498431796426555759572563984593048386193718910941358759029978447807867, 18421700152351889033425886605582046636055150850522264043268806719829411545064)]
p = 65451840317060754548721509248786919317953200359761627040412375309399869520573
a = 40809075131240948360173355414593271426621626350470877051694051260838563468807
b = 56001683003357145062129720078778094722953940399847954252272455929438505384318
Q_list = [(27451681917514871503343766469475486052295988988105475269724617063240940762102 : 22184028202016562681441217410758885518251488747255944296879939316545603572084 : 1), (32739503316597780479672878686767484514696477105377829712672969852958300789181 : 3451764148054691546855855367415859339796199578864689997675299139017990879292 : 1), (2718909433752551666770174094290041451531196486386042997591398533636776617144 : 23195453954249420930729360792345183044414320863228163459770919780499248440622 : 1)]
[*] Closed connection to localhost port 37773
[+] Opening connection to localhost on port 37773: Done
point_list = [(48546310525685667744470703979197869518385138656757328932942958798878247396730, 81819659043452584217923198828103493969259511816969856081551583236326995387896), (5591080739521784428376628432902968784370629800521481214465005144335595691248, 50054259818328726080388685211454650901235256054865699597187494066612608824226), (95298662322399781846240140125363833913524400078114630298382310558901587619564, 6630325333779398949306211222106483919078088614402393542280617754480471156317), (15768180901741050555615914720023824547010848038743059363731937038880008414030, 20754604019923346928811947698061314748965028036776216578457171410948836111537)]
p = 110913275916787446556100501188539065009722796467030113533121845162139452458427
a = 51102166338312898872141399433083127186060013139984285078447711254427715728419
b = 100265863877286779832866063683826243255003006735508453324763342297918242664058
Q_list = [(87359499294147883233730165425709272205875790046418324885629148416821682069493 : 21560599175885475287835526996018498474856062851138839655375347725943257327245 : 1), (22573774977566414253834008846196374490474215412666597578050309333025579704081 : 104069793797702606074647214300439505631687738737811154191051558696891875728680 : 1), (107787557987035269251981278030386507914899204761712591545802149159750279000960 : 107270140645172189341625085718883245748549056735955339008961533096136916356981 : 1)]
b'CCTF{prOm!nEn7_Z3n_Ikkyu_p03t?!}'
[*] Closed connection to localhost port 37773
CCTF{prOm!nEn7_Z3n_Ikkyu_p03t?!}

[Getting There] Mancity (98 solves)

Decipher Mancity by exploiting RSA modulus secrets, bit by bit, relation by relation.

問題の概要

この問題では以下のファイルが配布されています。

  • 暗号化に使用したPythonファイル (mancity.py)
  • 暗号化した出力結果が記載されたファイル (output.txt)

この問題は最初に256bitのランダムな素数 p が生成されます。  p を2進数に直したときの01をそれぞれ0111に変換した値を r としています。  p の2進数表現に1のビットを256個追加した値を q としています。  q, r が素数になるまでこの計算が繰り返されます。

 n = q r, e = 1234567891 として m を平文としたときに、 c = m^ e \bmod n として暗号文が計算されています。 出力結果には n, c が記載されています。

  • mancity.py
#!/usr/bin/env python3

from Crypto.Util.number import *
from flag import flag

def man(n):
    B = bin(n)[2:]
    M = ''
    for b in B:
        if b == '0':
            M += '01'
        else:
            M += '11'
    return int(M, 2)

def keygen(nbit):
    while True:
        p = getPrime(nbit)
        r = man(p)
        B = bin(p)[2:] + '1' * nbit
        q = int(B, 2)
        if isPrime(q) and isPrime(r):
                return q, r

nbit = 256
p, q = keygen(nbit)
m = bytes_to_long(flag)
assert m < n
e, n = 1234567891, p * q
c = pow(m, e, n)

print(f'n = {n}')
print(f'c = {c}')
  • output.txt
n = 147170819334030469053514652921356515888015711942553338463409772437981228515273287953989706666936875524451626901247038180594875568558137526484665015890594045767912340169965961750130156341999306808017498374501001042628249176543370525803456692022546235595791111819909503496986338431136130272043196908119165239297
c = 77151713996168344370880352082934801122524956107256445231326053049976568087412199358725058612262271922128984783428798480191211811217854076875727477848490840660333035334309193217618178091153472265093622822195960145852562781183839474868269109313543427082414220136748700364027714272845969723750108397300867408537

解法

 p の値が増加すると、 q  r 、そしてその積の n も増加する性質があります。 よって、 n が問題で与えられた値になるような p の値を二分探索によって求めることができます。  p の値が分かれば q, r の値も求められます。

 q, r の値が分かれば、後は通常のRSA暗号の復号手順に従って以下のように平文 m を計算すればフラグが得られます。

 \begin{align}
\phi \! \left( n \right) &= \left( q - 1 \right) \left( r - 1 \right) \\
d &\equiv e^ {-1} \pmod { \phi \! \left( n \right) } \\
m &= c^ d \bmod n
\end{align}
#!/usr/bin/env python3

from Crypto.Util.number import inverse, long_to_bytes


n = 147170819334030469053514652921356515888015711942553338463409772437981228515273287953989706666936875524451626901247038180594875568558137526484665015890594045767912340169965961750130156341999306808017498374501001042628249176543370525803456692022546235595791111819909503496986338431136130272043196908119165239297
c = 77151713996168344370880352082934801122524956107256445231326053049976568087412199358725058612262271922128984783428798480191211811217854076875727477848490840660333035334309193217618178091153472265093622822195960145852562781183839474868269109313543427082414220136748700364027714272845969723750108397300867408537

e = 1234567891
nbit = 256


def man(n):
    B = bin(n)[2:]
    M = ''
    for b in B:
        if b == '0':
            M += '01'
        else:
            M += '11'
    return int(M, 2)

def keygen(p):
    r = man(p)
    B = bin(p)[2:] + '1' * nbit
    q = int(B, 2)
    return q, r

def func(p):
    q, r = keygen(p)
    n = q * r
    return n


min_p, max_p = 0, 1 << nbit
while max_p - min_p > 1:
    d = max_p - min_p
    p = (min_p + max_p) // 2
    n_ = func(p)
    if n_ <= n:
        min_p = p
    else:
        max_p = p
p = min_p

q, r = keygen(p)
assert q * r == n
phi = (q - 1) * (r - 1)
d = inverse(e, phi)
m = pow(c, d, n)
print(long_to_bytes(m))
CCTF{M4nch3sReR_c0D!ng_wI7H_RSA}

[Getting There] Matemith (59 solves)

Solving Matemith’s polynomial equations is easier than pronouncing ‘Matemith’, but that’s not saying much!

問題の概要

この問題では以下のファイルが配布されています。

  • 暗号化に使用したSageMathファイル (matemith.sage)
  • 暗号化した出力結果が記載されたファイル (output.txt)

この問題では最初に素数 p が生成されます。 そして多項式 f', g', h', i', j', k' が以下のように定義されています。

 \begin{align}
f' \! \left( u, v, w, x, y, z \right) &= c _ 0 u v + c _ 1 u + c _ 2 v \\
g' \! \left( u, v, w, x, y, z \right) &= c _ 3 u x y + c _ 3 x + c _ 5 y + c _ 6 v \\
h' \! \left( u, v, w, x, y, z \right) &= c _ 7 u w + c _ 8 w + c _ 9 u \\
i' \! \left( u, v, w, x, y, z \right) &= c _ {10} v y z + c _ {11} y + c _ {12} z + c _ {13} w \\
j' \! \left( u, v, w, x, y, z \right) &= c _ {14} v w + c _ {15} v + c _ {16} w \\
k' \! \left( u, v, w, x, y, z \right) &= c _ {17} w z x + c _ {18} z + c _ {19} x + c _ {20} u
\end{align}

ここで、 c _ t \left( 0 \le t \lt 21 \right)  1 \le c _ t \lt p - 1 を満たすランダムな整数です。

フラグを l = 14 バイトごとに分割して整数に直したものを m _ 0, m _ 1, m _ 2, m _ 3, m _ 4, m _ 5 としています。 この値を使用して多項式 f が以下のように定義されています。

 \begin{align}
f \! \left( u, v, w, x, y, z \right) &= f' \! \left( u, v, w, x, y, z \right) - \left( f' \! \left( m _ 0, m _ 1, m _ 2, m _ 3, m _ 4, m _ 5 \right) \bmod p \right)
\end{align}

 g, h, i, j, k についても同様に定義されています。 出力結果には p, f, g, h, i, j, k が記載されています。

 c は問題のプログラムではCOEFSに対応しています。

  • matemith.sage
#!/usr/bin/env sage

from Crypto.Util.number import *
from flag import flag

l, flag = 14, flag.lstrip(b'CCTF{').rstrip(b'}')
FLAG = [flag[l * i:l * (i + 1)] for i in range(len(flag) // l)]
M = [bytes_to_long(_) for _ in FLAG]
p = getPrime(313)

R.<u, v, w, x, y, z> = PolynomialRing(QQ)

COEFS = [getRandomRange(1, p - 1) for _ in range(21)]

f = COEFS[0] * u * v + COEFS[1] * u + COEFS[2] * v
g = COEFS[3] * u * x * y + COEFS[3] * x + COEFS[5] * y + COEFS[6] * v
h = COEFS[7] * u * w + COEFS[8] * w + COEFS[9] * u
i = COEFS[10] * v * y * z + COEFS[11] * y + COEFS[12] * z + COEFS[13] * w
j = COEFS[14] * v * w + COEFS[15] * v + COEFS[16] * w
k = COEFS[17] * w * z * x + COEFS[18] * z + COEFS[19] * x + COEFS[20] * u

f, g, h, i, j, k = R(f), R(g), R(h), R(i), R(j), R(k)
CNST = [_(M[0], M[1], M[2], M[3], M[4], M[5]) for _ in [f, g, h, i, j, k]]
f, g, h, i, j, k = [[f, g, h, i, j, k][_] + (p - CNST[_]) % p for _ in range(6)]

print(f'{p = }')
print(f'{f = }')
print(f'{g = }')
print(f'{h = }')
print(f'{i = }')
print(f'{j = }')
print(f'{k = }')
  • output.txt

長いテキストファイルなので非表示(表示する場合はクリック)

p = 9892984422801315119260311427714389408772405421306235794826917610128461644036928139298330716261
f = 8593371583346286129538282168765198524220954884352992069219549555526097253129502925759872761483*u*v + 8192555264287905175212103898575474256555217842060435386769432116145712989123062847161390929397*u + 9598573789403814092125115160545174167539204328557118715540593719644188998531033259685435430387*v + 5738603225260621554442220996093767502015758942320213371600986432070445300427944977409453429117
g = 7737077144206080155196706693824644356475708615710271404071364943161652008584970269394416250641*u*x*y + 6282097687310252658473848438985225466620614743750918909885172321224925965646628839166491648752*v + 7737077144206080155196706693824644356475708615710271404071364943161652008584970269394416250641*x + 3354788147890488743832873565215769634619909759459203496980671578348799162553954862104978291860*y + 2560270290674636359252235177920929027441112715609783111306743340637878970846852799006820932563
h = 6107224904478508858527197508483774405356161856691777460732363192128980355274418091837270668258*u*w + 3584245173493717638976874408629921683995390608944250077841702023698807664457252845973088744491*u + 5646173287331462026544218972062953582608380797148923127395811758145598594972832047259631339566*w + 1994681139685786114971936867358158466232859433926848067961874687630342141141862187589124089741
i = 7622670835797214156123791992548663880284352234566921286637648219243086701251627093499322050472*v*y*z + 6026769215097777844835562389865313764490318485655789123763637718591748620654875700763740623760*w + 8145050175261359549200629067766090532616263522561328878195831921153188650784907223634130346224*y + 3622105614070476540808786980829452605696331317022729645355376801209444137548670550164418237117*z + 4800360746061605999597274870855047707130861888252519642520437605796496240599924899885487900040
j = 1912186465211454827473018892315659311053527670028135595953520151335825509122313783795561869379*v*w + 6246883466276200389231653597272295993565421216541002743075041326054203024921176043191679609212*v + 4002308425802254921531592700910138281674785127934610897914017993007060136199147207365547047048*w + 973159800079995512996976852328990077106942094656694887771601292254542762394381629810393447820
k = 1423338294606985951732736428034353751447528399559929388138157330118213387990891693204997290038*w*x*z + 784018806462384388182217012266169299116410899849461442885543245867941419322406775218178098109*u + 7684681843989505989596042520590550892565982707534588920361260899638313817214040416765327284778*x + 4982848574842913858489870338816729222210785430242027484672099513487039514577513464674726403409*z + 7781690757622738625626304200561818137843970209349935834539461705684625161407233281360563620790

解法

多項式 f の定義より、 u, v, w, x, y, z  m _ 0, m _ 1, m _ 2, m _ 3, m _ 4, m _ 5 を代入すると以下のようになります。

 \begin{align}
f \! \left( m _ 0, m _ 1, m _ 2, m _ 3, m _ 4, m _ 5 \right) &\equiv f' \! \left( m _ 0, m _ 1, m _ 2, m _ 3, m _ 4, m _ 5 \right) - \left( f' \! \left( m _ 0, m _ 1, m _ 2, m _ 3, m _ 4, m _ 5 \right) \bmod p \right) \\
&\equiv f' \! \left( m _ 0, m _ 1, m _ 2, m _ 3, m _ 4, m _ 5 \right) - f' \! \left( m _ 0, m _ 1, m _ 2, m _ 3, m _ 4, m _ 5 \right) \\
&\equiv 0 \pmod p
\end{align}

 g, h, i, j, k についても同様のことが成り立ちます。 よって、以下の連立方程式の解を計算すれば m _ 0, m _ 1, m _ 2, m _ 3, m _ 4, m _ 5 の値が求められます。

 \begin{align}
f \! \left( u, v, w, x, y, z \right) &\equiv 0 \pmod p \\
g \! \left( u, v, w, x, y, z \right) &\equiv 0 \pmod p \\
h \! \left( u, v, w, x, y, z \right) &\equiv 0 \pmod p \\
i \! \left( u, v, w, x, y, z \right) &\equiv 0 \pmod p \\
j \! \left( u, v, w, x, y, z \right) &\equiv 0 \pmod p \\
k \! \left( u, v, w, x, y, z \right) &\equiv 0 \pmod p
\end{align}

問題で与えられた多項式をよく見ると、 f, h, j  u, v, w のみが変数として含まれています。 3変数の式が3つあるので、これらを連立方程式として捉えて u, v, w の値を求めることができます。 連立方程式を解く際には終結式を使用して変数を消去して解を求めました*4

 m _ 0, m _ 1, m _ 2 の値が求まったのでそれらを残りの式の u, v, w に代入すると、変数が x, y, z のみの式が得られます。 そこで多項式 g'', i'', k'' を以下のように定めます。

 \begin{align}
g'' \! \left( x, y, z \right) &= g \! \left( m _ 0, m _ 1, m _ 2, x, y, z \right) \\
i'' \! \left( x, y, z \right) &= i \! \left( m _ 0, m _ 1, m _ 2, x, y, z \right) \\
k'' \! \left( x, y, z \right) &= k \! \left( m _ 0, m _ 1, m _ 2, x, y, z \right)
\end{align}

 g'', i'', k'' も3変数の3つの式なので、 f, h, j から m _ 0, m _ 1, m _ 2 を求めたときと同様にして g'', i'', k'' から m _ 3, m _ 4, m _ 5 を求めることができます。

 m _ 0, m _ 1, m _ 2, m _ 3, m _ 4, m _ 5 が求まれば、それらをバイト列に直して結合しフラグの形式に合わせれば、フラグが得られます。

#!/usr/bin/env sage


l = 14
R.<u, v, w, x, y, z> = PolynomialRing(QQ)

with open('output.txt', 'r') as f:
    output = f.read()
p, output = output.split('\n', maxsplit=1)
p = int(p.split(' = ')[-1])
f, g, h, i, j, k = [R(line.split(' = ')[-1]) for line in output.splitlines()]


def root(f, var):
    roots = f.polynomial(var).change_ring(GF(p)).roots(multiplicities=False)
    [root] = [root for root in roots if root < 2 ^ (8 * l)]
    return QQ(root)


w_ = root(f.resultant(h, u).resultant(j, v), w)
u_ = root(h.subs(w=w_), u)
v_ = root(f.subs(u=u_, w=w_), v)

g_, i_, k_ = [x.subs(u=u_, v=v_, w=w_) for x in [g, i, k]]
z_ = root(g_.resultant(i_, y).resultant(k_, x), z)
y_ = root(i_.subs(z=z_), y)
x_ = root(g_.subs(y=y_, z=z_), x)

flag_content = ''.join(int(i).to_bytes(l, 'big').decode() for i in [u_, v_, w_, x_, y_, z_])
print(f'CCTF{{{flag_content}}}')
CCTF{50lv!n6_7H3_H1dD3n__num8Ers_Pr08l3m_f0r_C51dH_4nd_C5uRf_v14_4uT0m473d_C0pp3r5m17h!!?}

[Getting There] Sobata (44 solves)

Master Sobata by dissecting ECC secrets, then tame its walk function’s hidden path.

nc 91.107.252.0 11177

問題の概要

この問題では以下のファイルが配布されています。

  • 問題サーバで動かしているSageMathプログラム (sobata.sage)

この問題では最初に p \bmod 6 = 1 を満たすランダムな素数 p が生成されます。  a \ne 1, b \ne 1 かつ a^ 3 = 1, b^ 2 = 1 を満たす有限体 \mathbb{F} _ p の要素 a, b と、ランダムな整数 c  \mathbb{F} _ p のランダムな要素 d が生成されます。 楕円曲線 E  y^ 2 = x^ 3 + d という式で定義されています。 平文 m  x 座標として持つ楕円曲線 E 上の点を P としています。 そのような点が存在しない場合は、 E 上の点が見つかるまで m の値が増やされます。

この問題では問題サーバに接続して以下の操作をすることができます。

  • 楕円曲線 E 上の点 P walk関数に渡した結果の取得
  • 楕円曲線 E 上の点 Q の入力と、それをwalk関数に渡した結果の取得
  • 楕円曲線 E 上の点 Q 、整数 n の入力と、それらをjump関数に渡した結果の取得

walk関数は楕円曲線 E 上の点 P = \left( x, y \right) を入力として、 Q = \left( a x, b y \right) が計算され、それを c (を整数に直した値)でスカラー倍したものが計算されます。 jump関数では c の代わりに c^ n \bmod o を使用したときのwalk関数の結果が計算されます。 ただし、 o は楕円曲線 E の位数とします。

  • sobata.sage
#!/usr/bin/env sage

import sys
from Crypto.Util.number import *
from flag import FLAG

def die(*args):
    pr(*args)
    quit()
    
def pr(*args):
    s = " ".join(map(str, args))
    sys.stdout.write(s + "\n")
    sys.stdout.flush()

def sc(): 
    return sys.stdin.buffer.readline()

def gen_params(nbit):
    while True:
        p = getPrime(nbit)
        if p % 6 == 1:
            F = GF(p)
            R = [F.random_element() for _ in '01']
            a, b = [R[_] ** ((p - 1) // (3 - _)) for _ in [0, 1]]
            if a != 1 and b != 1:
                c, d = [F.random_element() for _ in '01']
                E = EllipticCurve(GF(p), [0, d])
                return (p, E, a, b, c)

def walk(P, parameters):
    p, E, a, b, c = parameters
    x, y = P.xy()
    Q = (a * x, b * y)
    assert Q in E
    return int(c) * E(Q)

def jump(P, n, parameters):
    _parameters = list(parameters)
    _parameters[-1] = pow(int(_parameters[-1]), n, _parameters[1].order())
    return walk(P, _parameters)

def main():
    border = "┃"
    pr(        "┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓")
    pr(border, ".::               Welcome to the Sobata challenge!            ::. ", border)
    pr(border, " You should analyze this weird oracle and break it to get the flag", border)
    pr(        "┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛")
    nbit = 512
    parameters = gen_params(nbit)
    E = parameters[1]
    m = bytes_to_long(FLAG)
    assert m < parameters[0]
    while True:
        try:
            P = E.lift_x(m)
            break
        except:
            m += 1
    while True:
        pr("| Options: \n|\t[E]ncrypted FLAG \n|\t[W]alking with P \n|\t[J]umping over P \n|\t[Q]uit")
        ans = sc().decode().strip().lower()
        if ans == 'e':
            _P = walk(P, parameters)
            pr(border, f'The encrypted flag is: {_P.xy()}')
        elif ans == 'w':
            pr(border, 'Please send your desired point over E: ')
            Q = sc().decode().strip().split(',')
            try:
                Q = [int(_) for _ in Q]
            except:
                die(border, 'Your input is not valid!!')
            if Q in E:
                pr(border, f'The result of the walk is: {walk(E(Q), parameters).xy()}')
            else:
                die(border, 'Your point is not on the curve E! Bye!!')
        elif ans == 'j':
            pr(border, 'Send your desired point over E: ')
            Q = sc().decode().strip().split(',')
            pr(border, 'Let me know how many times you would like to jump over the given point: ')
            n = sc().decode().strip()       
            try:
                Q = [int(_) for _ in Q]
                n = int(n)
            except:
                die(border, 'Your input is not valid!!')
            if Q in E:
                pr(border, f'The result of the jump is: {jump(E(Q), n, parameters).xy()}')
            else:
                die(border, 'Your point is not on the curve E! Bye!!')
        elif ans == 'q': die(border, "Quitting...")
        else: die(border, "Bye...")

if __name__ == '__main__':
    main()
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃ .::               Welcome to the Sobata challenge!            ::.  ┃
┃  You should analyze this weird oracle and break it to get the flag ┃
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
| Options: 
|       [E]ncrypted FLAG 
|       [W]alking with P 
|       [J]umping over P 
|       [Q]uit
e
┃ The encrypted flag is: (3944231914668863676280791338676824109990823818008501643423828273625157116660751805333926240751380863610124531104289515665846427005012997172834092081429534, 1564257257423535067549548493822781237119786012110147070947762681210468818398855939470821324116644499929280496407083829897945958020239796773670131775798453)
| Options: 
|       [E]ncrypted FLAG 
|       [W]alking with P 
|       [J]umping over P 
|       [Q]uit
w
┃ Please send your desired point over E: 
3944231914668863676280791338676824109990823818008501643423828273625157116660751805333926240751380863610124531104289515665846427005012997172834092081429534,1564257257423535067549548493822781237119786012110147070947762681210468818398855939470821324116644499929280496407083829897945958020239796773670131775798453
┃ The result of the walk is: (4210570973872541427539878778594427079751325499659821876862952735355978996873501154439123676039138336454881392442895676766982942004495638495927448192035706, 10487611991752266269288542071097575142805561753332196092989228298838698527620772895807669838696924115132230808063438099837937076675589228911666907921306289)
| Options: 
|       [E]ncrypted FLAG 
|       [W]alking with P 
|       [J]umping over P 
|       [Q]uit
J
┃ Send your desired point over E: 
3944231914668863676280791338676824109990823818008501643423828273625157116660751805333926240751380863610124531104289515665846427005012997172834092081429534,1564257257423535067549548493822781237119786012110147070947762681210468818398855939470821324116644499929280496407083829897945958020239796773670131775798453
┃ Let me know how many times you would like to jump over the given point: 
2
┃ The result of the jump is: (2935023269907151607451080409988106178161594468721595536774035803734513528826272009309517349462740527284313394929503511025997450920596666035011855437877622, 3391810617640148783480377324601809690520531760945123113180516201473931794444245956861009071283840374299970561674383439995742648263652598471017220191239896)
| Options: 
|       [E]ncrypted FLAG 
|       [W]alking with P 
|       [J]umping over P 
|       [Q]uit

解法

まず、walk関数で使用されている P = \left( x, y \right)  Q = \left( a x, b y \right) に対応させる写像を F \! \left( P \right) = Q とします。 また、 O  E の無限遠点としたときに、 F \! \left( O \right) = O とします。 写像 F についての性質を考えると、 P = \left( x, y \right) が楕円曲線 E 上の点であれば、

 \begin{align}
\left( b y \right)^ 2 &= b^ 2 y^ 2 \\
&= y^ 2 \\
&= x^ 3 + d \\
&= a^ 3 x^ 3 + d \\
&= \left( a x \right)^ 3 + d
\end{align}

となり、 \left( b y \right)^ 2 = \left( a x \right)^ 3 + d が成り立つので Q = \left( a x, b y \right) も楕円曲線 E 上の点になります。 また、 P _ 1 = \left( x _ 1, y _ 1 \right), P _ 2 = \left( x _ 2, y _ 2 \right) を楕円曲線 E 上の点としたとき、以下のように F \! \left( P _ 1 + P _ 2 \right) = F \! \left( P _ 1 \right) + F \! \left( P _ 2 \right) が成り立ちます。

  •  P _ 1 = O の場合
     F \! \left( O + P _ 2 \right) = F \! \left( P _ 2 \right) = O + F \! \left( P _ 2 \right) = F \! \left( O \right) + F \! \left( P _ 2 \right)

  •  P _ 2 = O の場合
     F \! \left( P _ 1 + O \right) = F \! \left( P _ 1 \right) = F \! \left( P _ 1 \right) + O = F \! \left( P _ 1 \right) + F \! \left( O \right)

  •  x _ 1 = x _ 2, y _ 1 = -y _ 2 の場合
     a x _ 1 = a x _ 2, b y _ 1 = -b y _ 2 となるので、 F \! \left( P _ 1 + P _ 2 \right) = F \! \left( O \right) = O = F \! \left( P _ 1 \right) + F \! \left( P _ 2 \right)

  •  x _ 1 = x _ 2, y _ 1 = y _ 2 の場合
     P _ 1 + P _ 2 = \left( x _ 3, y _ 3 \right) としたときに、

 \begin{align}
s &= \frac{3 x _ 1^ 2}{2 y _ 1} \\
x _ 3 &= s^ 2 - 2 x _ 1 \\
y _ 3 &= y _ 1 + s \left( x _ 3 - x _ 1 \right)
\end{align}

となり、 F \! \left( P _ 1 \right) + F \! \left( P _ 2 \right) = \left( x' _ 3, y' _ 3 \right) としたときに、

 \begin{align}
s' &= \frac{3 \left( a x _ 1 \right)^ 2}{2 \left( b y _ 1 \right)} = \frac{a^ 2}{b} \frac{3 x _ 1^ 2}{2 y _ 1} = \frac{a^ 2}{b} s \\
x' _ 3 &= s'^ 2 - 2 \left( a x _ 1 \right) = \left( \frac{a^ 2}{b} s \right)^ 2 - 2 a x _ 1 = a \left( s^ 2 - 2 x _ 1 \right) = a x _ 3 \\
y' _ 3 &= \left( b y _ 1 \right) + s' \left( \left( a x _ 3 \right) - \left( a x _ 1 \right) \right) = b y _ 1 + \left( \frac{a^ 2}{b} s \right) a \left( x _ 3 - x _ 1 \right) = b \left( y _ 1 + s \left( x _ 3 - x _ 1 \right) \right) = b y _ 3
\end{align}

が成り立つので、 F \! \left( P _ 1 + P _ 2 \right) = F \! \left( \left( x _ 3, y _ 3 \right) \right) = \left( a x _ 3, b y _ 3 \right) = \left( x' _ 3, y' _ 3 \right) = F \! \left( P _ 1 \right) + F \! \left( P _ 2 \right) となります。

  • その他の場合
     P _ 1 + P _ 2 = \left( x _ 3, y _ 3 \right) としたときに、
 \begin{align}
s &= \frac{y _ 1 - y _ 2}{x _ 1 - x _ 2} \\
x _ 3 &= s^ 2 - x _ 1 - x _ 2 \\
y _ 3 &= y _ 1 + s \left( x _ 3 - x _ 1 \right)
\end{align}

となり、 F \! \left( P _ 1 \right) + F \! \left( P _ 2 \right) = \left( x' _ 3, y' _ 3 \right) としたときに、

 \begin{align}
s' &= \frac{\left( b y _ 1 \right) - \left( b y _ 2 \right)}{\left( a x _ 1 \right) - \left( a x _ 2 \right)} = \frac{b}{a} \frac{y _ 1 - y _ 2}{x _ 1 - x _ 2} = \frac{b}{a} s \\
x' _ 3 &= s'^ 2 - \left( a x _ 1 \right) - \left( a x _ 2 \right) = \left( \frac{b}{a} s \right)^ 2 - a \left( x _ 1 - x _ 2 \right) = a \left( s^ 2 - x _ 1 - x _ 2 \right) = a x _ 3 \\
y' _ 3 &= \left( b y _ 1 \right) + s' \left( \left( a x _ 3 \right) - \left( a x _ 1 \right) \right) = b y _ 1 + \left( \frac{b}{a} s \right) a \left( x _ 3 - x _ 1 \right) = b \left( y _ 1 + s \left( x _ 3 - x _ 1 \right) \right) = b y _ 3
\end{align}

が成り立つので、 F \! \left( P _ 1 + P _ 2 \right) = F \! \left( \left( x _ 3, y _ 3 \right) \right) = \left( a x _ 3, b y _ 3 \right) = \left( x' _ 3, y' _ 3 \right) = F \! \left( P _ 1 \right) + F \! \left( P _ 2 \right) となります。

 F \! \left( P _ 1 + P _ 2 \right) = F \! \left( P _ 1 \right) + F \! \left( P _ 2 \right) となるので、 F \! \left( s P \right) = s F \! \left( P \right) も成り立ちます。 さらに、楕円曲線 E 上の点 P = \left( x, y \right) に写像 F  6 回適用すると、

 \begin{align}
F^ 6 \! \left( P \right) &= F \! \left( F \! \left( F \! \left( F \! \left( F \! \left( F \! \left( P \right) \right) \right) \right) \right) \right) \\
&= \left( a^ 6 x, b^ 6 y \right) \\
&= \left( x, y \right) \\
&= P
\end{align}

となり、 F^ 6 \! \left( P \right) = P が成り立ちます。

写像 F を使用してwalk関数とjump関数を式で表すと以下のようになります。

 \begin{align}
\mathrm{walk} \! \left( P, c \right) &= c F \! \left( P \right) \\
\mathrm{jump} \! \left( P, n, c \right) &= c^ n F \! \left( P \right)
\end{align}

フラグを楕円曲線 E 上の点に変換したものを \left( x _ 0, y _ 0 \right) とすると、 \left( x _ 1, y _ 1 \right) = \mathrm{walk} \! \left( \left( x _ 0, y _ 0 \right), c \right) = c F \! \left( \left( x _ 0, y _ 0 \right) \right) の値を取得することができます。  \left( x _ 0, y _ 0 \right) walk関数を k 回適用したものを \left( x _ k, y _ k \right) とすると、 \left( x _ k, y _ k \right) = c^ k F^ k \! \left( \left( x _ 0, y _ 0 \right) \right) が成り立ちます。 また、 r = 6 - 1 とすると F^ {r + 1} \! \left( P \right) = F^ 6 \! \left( P \right) = P が成り立ちます。 そこで、 n = -r としてjump関数を \left( x _ r, y _ r \right) に適応すると以下のようになります。

 \begin{align}
\mathrm{jump} \! \left( \left( x _ r, y _ r \right), -r, c \right) &= c^ {-r} F \! \left( \left( x _ r, y _ r \right) \right) \\
&= c^ {-r} F \! \left( c^ r F^ r \! \left( \left( x _ 0, y _ 0 \right) \right) \right) \\
&= c^ {-r} c^ r F \! \left( F^ r \! \left( \left( x _ 0, y _ 0 \right) \right) \right) \\
&= F^ {r + 1} \! \left( \left( x _ 0, y _ 0 \right) \right) \\
&= \left( x _ 0, y _ 0 \right)
\end{align}

このようにして \left( x _ 1, y _ 1 \right) から \left( x _ 0, y _ 0 \right) の値を計算することができるので、フラグを取得することができます。

#!/usr/bin/env python3

from pwn import remote
from Crypto.Util.number import long_to_bytes


# host = '91.107.161.140'
# host = '91.107.133.165'
host = 'localhost'
port = 11177


def select_word(b, nl, nw):
    return b.splitlines()[nl].split(b' ')[nw]


with remote(host, port) as conn:
    conn.recvuntil(b'[Q]uit\n')
    conn.sendline(b'E')
    data = conn.recvuntil(b'[Q]uit\n')
    x1, y1 = list(map(int, data.splitlines()[0].strip('┃ The encrypted flag is: ()'.encode()).split(b', ')))
    print(f'{(x1, y1) = }')
    
    x, y = x1, y1
    r = 6 - 1
    for _ in range(r - 1):
        conn.sendline(b'W')
        conn.recvuntil(b'Please send your desired point over E: \n')
        conn.sendline(f'{x}, {y}'.encode())
        data = conn.recvuntil(b'[Q]uit\n')
        x, y = list(map(int, data.splitlines()[0].strip('┃ The result of the walk is: ()'.encode()).split(b', ')))
        print(f'{(x, y) = }')

    xr, yr = x, y
    n = -r
    conn.sendline(b'J')
    conn.recvuntil(b'Send your desired point over E: \n')
    conn.sendline(f'{xr}, {yr}'.encode())
    conn.recvuntil(b'Let me know how many times you would like to jump over the given point: \n')
    conn.sendline(str(n).encode())
    data = conn.recvuntil(b'[Q]uit\n')
    x, y = list(map(int, data.splitlines()[0].strip('┃ The result of the jump is: ()'.encode()).split(b', ')))
    print(f'{(x, y) = }')

m = x
flag = long_to_bytes(m)
flag = flag[:-1] + b'}'
print(flag)
$ cp ./solve.sage
[+] Opening connection to localhost on port 11177: Done
(x1, y1) = (73287751455412304206814829878968636696924354660810083864076852600000340851532218807505410120170160040346618387962555370444309909876039621014177044303121, 7427941842723091371644158697375355085935323582743356596163604023960779913506314710578034873730647973038481432637569906264793263155672134904369458860589958)
(x, y) = (10579060503599920805157119471647456973163796605467259093086809187765514880648396359924548142739888850082008071447385858674435536123008472077497738101167788, 6891297696136913657516819725179373339624711729587551554932201513736226950031765987810446114293911874474336095167396251502664397455417874132354137045655246)
(x, y) = (6833669666475860266100834018345637132304172376650448494086792602052201594427432885035016737973472601887112998131207804570413301407803106914129533605679025, 10898973284618649376180183709429613274262333827557598503842175838847872866381265368241565269411928047856459851015583250762268615144786578893204435368651617)
(x, y) = (7717786256756099362979748825586897167583776820482084167317724833798417332798670217185856309912354501607927886332240126330785135858453375793151041341659618, 8287861325412281966685346963642462786890681513746226244547721028160400187412941964314344179816088491551419060637656922852377799979038817879036585138069630)
(x, y) = (2343628142933689102337019719299732078863923781817356618515172742222599667903399310873023411943856428599999767962382900772490424074091314780668145204062594, 4238383603071209584943151479638040871884706930625469962664975195454683407385422697779394166400270258628902029914407644730992314700958582692232486601954199)
(x, y) = (118843442403488878017662153140228666578021080047461066797802948818418999679, 1069529664954577089736096492702065992887613319858911179169330030663951904860496259415801863171990937152170803127358687655277768104941634559727740775644488)
[*] Closed connection to localhost port 11177
b'CCTF{L1n3Ari7y_iN_w4lkIn9_ECC!}'
CCTF{L1n3Ari7y_iN_w4lkIn9_ECC!}

[Getting There] Vainrat (67 solves)

Precision is key, Vainrat escapes sluggish calculators effortlessly.

nc 91.107.252.0 11117

問題の概要

この問題では以下のファイルが配布されています。

  • 問題サーバで動かしているSageMathプログラム (vainrat.sage)

この問題では最初に平文を m mの桁数を l としたときに x _ 0 = 10^ {-l} m としています。  y _ 0 \gt x _ 0 を満たすランダムな実数 y _ 0 が生成されて表示されます。

 i \ge 1 を満たす整数 i に対して、 x _ i, y _ i が以下のように定義されています。

 \begin{align}
x _ i &= \frac{1}{2} \left( x _ {i - 1} + y _ {i - 1} \right) \\
y _ i &= \left( x _ {i - 1} y _ {i - 1} \right)^ \frac{1}{2}
\end{align}

 i = 1 から順番に x _ i, y _ i  12 \le r _ i \le 19 を満たすランダムな整数 r _ i が計算され、 i \gt r _ i であれば y _ i が表示されます。

  • vainrat.sage
#!/usr/bin/env sage

import sys
from Crypto.Util.number import *
from flag import flag

def die(*args):
    pr(*args)
    quit()
    
def pr(*args):
    s = " ".join(map(str, args))
    sys.stdout.write(s + "\n")
    sys.stdout.flush()

def sc(): 
    return sys.stdin.buffer.readline()

nbit = 110
prec = 4 * nbit
R = RealField(prec)

def rat(x, y):
    x = R(x + y) * R(0.5)
    y = R((x * y) ** 0.5)
    return x, y

def main():
    border = "┃"
    pr(        "┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓")
    pr(border, ".::               Welcome to Vain Rat challenge!              ::. ", border)
    pr(border, " You should chase the vain rat and catch it to obtain the flag!   ", border)
    pr(        "┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛")
    m = bytes_to_long(flag)
    x0 = R(10 ** (-len(str(m))) * m)
    while True:
        y0 = abs(R.random_element())
        if y0 > x0: break
    assert len(str(x0)) == len(str(y0))
    c = 0
    pr(border, f'We know y0 = {y0}')
    while True:
        pr("| Options: \n|\t[C]atch the rat \n|\t[Q]uit")
        ans = sc().decode().strip().lower()
        if ans == 'c':
            x, y = rat(x0, y0)
            x0, y0 = x, y
            c += 1
            if c <= randint(12, 19):
                pr(border, f'Unfortunately, the rat got away :-(')
            else: pr(border, f'y = {y}')
        elif ans == 'q': die(border, "Quitting...")
        else: die(border, "Bye...")

if __name__ == '__main__':
    main()
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃ .::               Welcome to Vain Rat challenge!              ::.  ┃
┃  You should chase the vain rat and catch it to obtain the flag!    ┃
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
┃ We know y0 = 0.743135989204170192962212954444820178171812335398736151041343622181469919647585692708527401526403672396302394191691878416407365739314
| Options: 
|       [C]atch the rat 
|       [Q]uit
c
┃ Unfortunately, the rat got away :-(
| Options: 
|       [C]atch the rat 
|       [Q]uit
c
┃ Unfortunately, the rat got away :-(
| Options: 
|       [C]atch the rat 
|       [Q]uit
c
┃ Unfortunately, the rat got away :-(
| Options: 
|       [C]atch the rat 
|       [Q]uit
c
┃ Unfortunately, the rat got away :-(
| Options: 
|       [C]atch the rat 
|       [Q]uit
c
┃ Unfortunately, the rat got away :-(
| Options: 
|       [C]atch the rat 
|       [Q]uit
c
┃ Unfortunately, the rat got away :-(
| Options: 
|       [C]atch the rat 
|       [Q]uit
c
┃ Unfortunately, the rat got away :-(
| Options: 
|       [C]atch the rat 
|       [Q]uit
c
┃ Unfortunately, the rat got away :-(
| Options: 
|       [C]atch the rat 
|       [Q]uit
c
┃ Unfortunately, the rat got away :-(
| Options: 
|       [C]atch the rat 
|       [Q]uit
c
┃ Unfortunately, the rat got away :-(
| Options: 
|       [C]atch the rat 
|       [Q]uit
c
┃ Unfortunately, the rat got away :-(
| Options: 
|       [C]atch the rat 
|       [Q]uit
c
┃ Unfortunately, the rat got away :-(
| Options: 
|       [C]atch the rat 
|       [Q]uit
c
┃ y = 0.721455014397622672958999043358847095881511027160678633904969331816526958252746239782158128408145122833464128227503142763008149777226
| Options: 
|       [C]atch the rat 
|       [Q]uit

解法

 i \ge 1 に対する y _ i の中で、値が既知のものを y _ n とします。  x _ 0 の値は未知なので、 x _ 0 の仮の値を x' _ 0 とします。  x' _ 0, y _ 0 を使用して計算したものを x' _ n, y' _ n とします。

 x' _ n, y' _ n の性質として、 x' _ 0 の値が増加すると、 x' _ n, y' _ n も増加する性質があります。 よって、 y' _ n  y _ n に近い値になるような x' _ 0 の値を二分探索によって求めることができます。 このとき x' _ 0  x _ 0 に近い値になると考えられます。

 x' _ 0  x _ 0 に十分近ければ、 10^ l x' _ 0 を整数に丸めることにより m を計算することができ、フラグを取得することができます。

#!/usr/bin/env sage

from pwn import remote
from Crypto.Util.number import long_to_bytes


# host = '91.107.252.0'
host = 'localhost'
port = 11117


def select_word(b, nl, nw):
    return b.splitlines()[nl].split(b' ')[nw]


nbit = 110
prec = 4 * nbit
R = RealField(prec)

def rat(x, y):
    x = R(x + y) * R(0.5)
    y = R((x * y) ** 0.5)
    return x, y

def make_func(y0, n):
    def func(x0):
        x, y = x0, y0
        for _ in range(n):
            x, y = rat(x, y)
        return y
    return func


with remote(host, port) as conn:
    n = 0
    data = conn.recvuntil(b'[Q]uit\n')
    y0 = R(select_word(data, 4, -1).decode())
    
    while True:
        conn.sendline(b'C')
        data = conn.recvuntil(b'[Q]uit\n')
        n += 1
        if not data.startswith('┃ Unfortunately, the rat got away :-('.encode()):
            break
    yn = R(select_word(data, 0, -1).decode())

print(f'{y0 = }')
print(f'{yn = }')
print(f'{n = }')

func = make_func(y0, n)
min_x, max_x = R(0), y0
d = None
while max_x - min_x != d:
    d = max_x - min_x
    x = (min_x + max_x) / R(2)
    y = func(x)
    if y < yn:
        min_x = x
    else:
        max_x = x

print(f'{x = }')
l = 120
m = round(x * 10 ^ l)
print(long_to_bytes(m))
$ ./solve.sage
[+] Opening connection to localhost on port 11117: Done
[*] Closed connection to localhost port 11117
y0 = 0.800583116466350979107521953479122147389322541581461123714089371612663337014167463729680676900382180491497588044958471800125285012556
yn = 0.759451142635868206031160943249737175914227495830265012792998172223562880435359750290626816033742150839101808381684179572417425018553
n = 17
x = 0.678476115854709485500044951354299580150888171940281786813194398218373542184809765526189109749723424080338331287485227389000000000000
b'CCTF{h3Ur1s7!c5_anD_iNv4rIanTs_iN_CryptoCTF_2025!}'
CCTF{h3Ur1s7!c5_anD_iNv4rIanTs_iN_CryptoCTF_2025!}

難易度Tough Cookieの問題についてのWriteup

These 0s and 1s have the digital handwriting of a drunk Ph.D., trace their signature, sign your own name, and leak their crayon-scrawled Lowdown.

nc 91.107.252.0 31113

問題の概要

この問題では以下のファイルが配布されています。

  • 問題サーバで動かしているSageMathプログラム (lowdown.sage)

この問題では最初に k = 10 として、 \mathbb{F} _ {2^ 8} 上の k  k 列のランダムな行列 g が生成されます。  2 \le r \le 2^ {192} - 2, 2 \le a \le 2^ {192} - 2 を満たすランダムな整数 r, a が生成され、行列 b  b = g^ {r a} というように計算されています。

この問題では問題サーバに接続して以下の操作をすることができます。

  • フラグの取得
  • 10バイト未満のメッセージに対する署名の取得
  • 署名の検証
  • 公開鍵 g, b の取得

メッセージ m に対する署名 s, t は以下のようにして計算されています。

 \begin{align}
s &= b g^ {-r n H \! \left( m \right)} \\
t &= g^ {r n}
\end{align}

ただし、 n  2 \le n \le 2^ {192} - 2 を満たすランダムな整数、 H は適当なハッシュ関数でこの問題ではSHA-1が使用されています。 署名の検証は s t^ {H \! \left( m \right)} = b が成り立つかどうかが確認されます。

フラグを取得するためには、ランダムに生成された40バイトのメッセージに対する署名 s, t を入力します。 入力した署名が以下の条件を満たす場合にフラグが表示されます。

  • 入力した署名が正当なものであること
  •  s を10進数表現に直したときに13で始まること
  •  t を10進数表現に直したときに37で始まること

行列と整数の変換にはこの問題のプログラムで定義されているM2i関数とHinv関数が使用されています。

 b, m は問題のプログラムではga, msgに対応しています。

  • lowdown.sage
#!/usr/bin/env sage

import sys, string
from Crypto.Util.number import *
from hashlib import sha1
from flag import flag

def die(*args):
    pr(*args)
    quit()

def pr(*args):
    s = " ".join(map(str, args))
    sys.stdout.write(s + "\n")
    sys.stdout.flush()

def sc():
    return sys.stdin.buffer.readline()

def h(a):
    if a == 0:
        return 0
    else:
        g = F.gen()
        for _ in range(1, 256):
            if g ** _ == a:
                return _

def H(M):
    assert M.nrows() == M.ncols()
    k, _H = M.nrows(), []
    for i in range(k):
        for j in range(k):
            _h = h(M[i, j])
            _H.append(bin(_h)[2:].zfill(8))
    return ''.join(_H)

def Hinv(m, k):
    B = bin(m)[2:].zfill(8 * k**2)
    g = F.gen()
    _H = [int(B[8*i:8*i + 8], 2) for i in range(k**2)]
    _M = [0 if _h == 0 else g ** _h for _h in _H]
    M = Matrix(F, [[a for a in _M[k*i:k*i + k]] for i in range(k)])
    return M

def M2i(M):
    _H = H(M)
    return int(_H, 2)

def random_oracle(msg):
    _h = sha1(msg).digest()
    return bytes_to_long(_h)

def makey(k):
    while True:
        g = random_matrix(F, k)
        if g.is_invertible():
            ng = 1 << 192 # g.order()
            break
    r, a = [randint(2, ng - 2) for _ in '01']
    gg = g ** r
    pkey, skey = (g, gg ** a), r
    return(pkey, skey)

def sign(pkey, skey, msg):
    g, ga = pkey
    ng = 1 << 192 # g.order()
    _h = random_oracle(msg)
    assert _h <= ng
    _g = g ** skey
    n = randint(2, ng - 2)
    s, t = ga * (_g.inverse()) ** (n * _h), _g ** n
    return (s, t)

def verify(sgn, pkey, msg):
    _, ga = pkey
    s, t = sgn
    _h = random_oracle(msg)
    return s * t ** _h == ga

def main():
    border = "┃"
    pr("┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓")
    pr(border, "Hi all, now it's time to sign a given message in a strange signature", border)
    pr(border, "schema. You will receive the flag if you are able to sign a message.", border)
    pr("┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛")

    global F, k
    F = GF(256)
    k = 10
    pkey, skey = makey(k)

    msg = ''.join([string.printable[randint(0, 85)] for _ in range(40)]).encode()

    while True:
        pr("| Options: \n|\t[G]et the flag \n|\t[P]ublic Key \n|\t[S]ign a message \n|\t[V]erify signature \n|\t[Q]uit")
        ans = sc().decode().lower().strip()
        if ans == 'g':
            pr(border, 'You should send the valid signature for my given message!')
            pr(border, f'Message = {msg}')
            pr(border, 'Send the signature of the above message: ')
            _sgn = sc().split(b',')
            try:
                _s, _t = [int(_) for _ in _sgn]
                sgn = (Hinv(_s, k), Hinv(_t, k))
                if verify(sgn, pkey, msg) and str(_s).startswith('13') and str(_t).startswith('37'):
                    pr(border, f'Congratulation! You got the flag!')
                    die(border, f'flag = {flag}')
                else:
                    pr(border, 'Your signature is not correct!')
            except:
                die(border, 'Exiting...')
        elif ans == 's':
            pr(border, 'Send your message to sign: ')
            _msg = sc().strip()
            if len(_msg) >= 10:
                die(border, 'Sorry, I sign only short messages! :/')
            _s, _t = sign(pkey, skey, _msg)
            pr(border, f's = {M2i(_s)}')
            pr(border, f't = {M2i(_t)}')
        elif ans == 'v':
            pr(border, 'Send your signature to verify: ')
            _sgn = sc().split(b',')
            try:
                _s, _t = [int(_) for _ in _sgn]
                _sgn = (Hinv(_s, k), Hinv(_t, k))
                pr(border, 'Send your message: ')
                _msg = sc().strip()
                if verify(_sgn, pkey, _msg):
                    pr(border, 'Your message successfully verified :)')
                else:
                    pr(border, 'Verification failed :(')
            except:
                pr(border, 'Try to send valid signature!')
                continue
        elif ans == 'p':
            _g, _ga = pkey
            pr(border, f'g  = {M2i(_g)}')
            pr(border, f'ga = {M2i(_ga)}')
        elif ans == 'q':
            die(border, 'Quitting...')
        else:
            die(border, 'You should select valid choice!')

if __name__ == '__main__':
    main()
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃ Hi all, now it's time to sign a given message in a strange signature ┃
┃ schema. You will receive the flag if you are able to sign a message. ┃
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
| Options: 
|       [G]et the flag 
|       [P]ublic Key 
|       [S]ign a message 
|       [V]erify signature 
|       [Q]uit
p
┃ g  = 1225869591345456514740049340153878988749516400099250084322522766630759930603565075058109314443115053580818148550421284487525088885384589454945600085824178474272699648863246422532454654339315709844810113214392666319767307488574176764260633647
┃ ga = 434912560313957269003004737638806609180518910381404020240578037803059910602752317792829217476133724540804746458137914848860195988817106102941835247104342916459965876795786630946235634168345186643847800209293574475431021943202478292727110655
| Options: 
|       [G]et the flag 
|       [P]ublic Key 
|       [S]ign a message 
|       [V]erify signature 
|       [Q]uit
s
┃ Send your message to sign: 
test_msg
┃ s = 2233154473270607882617676807920061259080323677486647083748825361483912085751523509265682534507827414198525623423356221647619456327657916836927286148483088362471668137231414677853184247023682684952118110950581755898733026582535590570475919072
┃ t = 5312109127106094563249421809388914819296497031402218434207923162917374923848756718243057557767942947669065215838136346953099866207169524046215538075132217872255616007793595015383050381481215831707555454517404797255135131591213656480704284565
| Options: 
|       [G]et the flag 
|       [P]ublic Key 
|       [S]ign a message 
|       [V]erify signature 
|       [Q]uit
v
┃ Send your signature to verify: 
2233154473270607882617676807920061259080323677486647083748825361483912085751523509265682534507827414198525623423356221647619456327657916836927286148483088362471668137231414677853184247023682684952118110950581755898733026582535590570475919072,5312109127106094563249421809388914819296497031402218434207923162917374923848756718243057557767942947669065215838136346953099866207169524046215538075132217872255616007793595015383050381481215831707555454517404797255135131591213656480704284565
┃ Send your message: 
test_msg
┃ Your message successfully verified :)
| Options: 
|       [G]et the flag 
|       [P]ublic Key 
|       [S]ign a message 
|       [V]erify signature 
|       [Q]uit
g
┃ You should send the valid signature for my given message!
┃ Message = b'PJGA[vt5&:$7L!c;j7Z%3"i.&:8L;I<W(<?QPz-x'
┃ Send the signature of the above message: 
2233154473270607882617676807920061259080323677486647083748825361483912085751523509265682534507827414198525623423356221647619456327657916836927286148483088362471668137231414677853184247023682684952118110950581755898733026582535590570475919072,5312109127106094563249421809388914819296497031402218434207923162917374923848756718243057557767942947669065215838136346953099866207169524046215538075132217872255616007793595015383050381481215831707555454517404797255135131591213656480704284565
┃ Your signature is not correct!
| Options: 
|       [G]et the flag 
|       [P]ublic Key 
|       [S]ign a message 
|       [V]erify signature 
|       [Q]uit

解法

問題サーバで生成されたメッセージを m とします。 10進数表現が37で始まるランダムな整数を t とします。  t を行列に変換してから以下のようにして s を計算します。

 \begin{align}
s &= b t^ {-H \! \left( m \right)}
\end{align}

 s を整数に変換したときに、10進数表現が13で始まるかを確認します。 条件を満たすまで t, s の計算を繰り返します。

計算した s, t を問題サーバに入力すると、フラグが表示されます。

#!/usr/bin/env sage

from pwn import remote
from hashlib import sha1
from Crypto.Util.number import bytes_to_long
from ast import literal_eval


# host = '91.107.132.34'
host = 'localhost'
port = 31113


def select_word(b, nl, nw):
    return b.splitlines()[nl].split(b' ')[nw]


def h(a):
    if a == 0:
        return 0
    else:
        g = F.gen()
        for _ in range(1, 256):
            if g ** _ == a:
                return _

def H(M):
    assert M.nrows() == M.ncols()
    k, _H = M.nrows(), []
    for i in range(k):
        for j in range(k):
            _h = h(M[i, j])
            _H.append(bin(_h)[2:].zfill(8))
    return ''.join(_H)

def Hinv(m, k):
    B = bin(m)[2:].zfill(8 * k**2)
    g = F.gen()
    _H = [int(B[8*i:8*i + 8], 2) for i in range(k**2)]
    _M = [0 if _h == 0 else g ** _h for _h in _H]
    M = Matrix(F, [[a for a in _M[k*i:k*i + k]] for i in range(k)])
    return M

def M2i(M):
    _H = H(M)
    return int(_H, 2)

def random_oracle(msg):
    _h = sha1(msg).digest()
    return bytes_to_long(_h)


F = GF(256)
k = 10

with remote(host, port) as conn:
    conn.recvuntil(b'[Q]uit\n')
    conn.sendline(b'P')
    data = conn.recvuntil(b'[Q]uit\n')
    g = Hinv(int(select_word(data, 0, -1)), k)
    ga = Hinv(int(select_word(data, 1, -1)), k)
    print(f'{M2i(g) = }')
    print(f'{M2i(ga) = }')
    
    conn.sendline(b'G')
    data = conn.recvuntil(b'Send the signature of the above message: \n')
    msg = literal_eval(data.splitlines()[1].decode().removeprefix('┃ Message = '))
    print(f'{msg = }')
    
    b = ga
    
    _h = random_oracle(msg)
    t_digits = floor(log((2 ^ 8) ^ (k ^ 2) / 37, 10))
    _s = 0
    while not str(_s).startswith('13'):
        _t = 37 * 10 ^ t_digits + randrange(10 ^ t_digits)
        t = Hinv(_t, k)
        try:
            s = b * t ^ -_h
        except ZeroDivisionError:
            continue
        _s = M2i(s)
    print(f'{_s = }')
    print(f'{_t = }')
    
    conn.sendline(f'{_s}, {_t}'.encode())
    data = conn.recvall()
    flag = select_word(data, 1, -1).decode()
    print(flag)
$ ./solve.sage
[+] Opening connection to localhost on port 31113: Done
M2i(g) = 4115919195643379026055201108464007116449142511655436313202245078230702492273244197868561277398824338942498591037199006573228111559171281688736097562003988296677562981202959203974675981238298364459455021833636951721096286960952710514485791858
M2i(ga) = 1971532714396165162312010580482500018742338003995084942625101988771969666019637027031802064322899705900471401414173602165396309666651863544321486932364282031587731226156763804977673945021328233631185503980964222669101859169770934445388244260
msg = b'9gq)GiQ+?Sd\\Uu-s8Wom2U[TzHhBa$\\V;j9ePTid'
_s = 1390951032636354351345778035195361720454247016292963514176699121098236144302458389335754583608672879452254877413180244225107490804515429134516777138739195681975516125996441544465835257703280859523925827947782885006344901444069128337491896932
_t = 3757694611007370447096310849456479293290549724966655139290835027337213812287022555018072908898963573103684650535233731805116409643618805320774505390451602958533911505616025276089694663612087978903710127428846331138323688514227355186657070378
[+] Receiving all data: Done (124B)
[*] Closed connection to localhost port 31113
b'CCTF{F0r9erY_At7acK_!nd3Pend3nT_oF_7hE_h4rDn3sS_0f_DLP!}'
CCTF{F0r9erY_At7acK_!nd3Pend3nT_oF_7hE_h4rDn3sS_0f_DLP!}

Mechanic II cranks PQC to hilarious levels, bring a quantum wrench and a PhD in pain.

nc 91.107.252.0 11111

Note: Please re-download the attachment!

問題の概要

この問題では以下のファイルが配布されています。

  • 問題サーバで動かしているPythonプログラム (mechanic_ii.py)

この問題では暗号化の処理にML-KEM-1024というアルゴリズムが使用されています。 最初に n = 1337 としたときに、公開鍵と秘密鍵のペアが n 個生成されます。  0 \le r \lt n を満たす整数 r と共通鍵が生成され、 r 番目の公開鍵を使用して共通鍵が暗号化されます。 共通鍵を元にsecretという変数が計算されます。

この問題では問題サーバに接続して以下の操作をすることができます。

  • 共通鍵の復号
  • 秘密鍵の追加
  • secretの値の入力

問題サーバでの操作は 3 n + 1 回まで行うことができます。

共通鍵の復号では、整数 i を入力すると、 i 番目の秘密鍵を使用して共通鍵を復号した結果が返されます。 秘密鍵の追加では、 i 番目の秘密鍵の末尾32バイトがランダムなバイト列に置き換えられ、それが秘密鍵のリストの末尾に追加されます。 secretの値の入力したときに正しい値であればフラグが表示されます。

  • mechanic_ii.py
#!/usr/bin/env python3

from quantcrypt.kem import MLKEM_1024
import sys, os, string
from random import randint
import hashlib
from flag import flag

def die(*args):
    pr(*args)
    quit()
    
def pr(*args):
    s = " ".join(map(str, args))
    sys.stdout.write(s + "\n")
    sys.stdout.flush()
    
def sc():
    return sys.stdin.buffer.readline()

def rand_str(l):
    charset = string.printable[:63] + '_'
    return ''.join([charset[randint(0, 63)] for _ in range(l)]).encode()

def pow():
    head = rand_str(15)
    tail = rand_str(4)
    h = hashlib.sha3_256(head + tail).hexdigest()
    return head, h

def main():
    border = "┃"
    pr(        "┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓")
    pr(border, ".:::       Welcome to the Mechanic II cryptography task!      ::.", border)
    pr(border, "Your mission is to find flag by analyzing this amazing Oracle! :)", border)
    pr(        "┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛")
    head, h = pow()
    pr(border, f'Please pass the proof of work first: {head, h}')
    _tail = sc().strip()
    if hashlib.sha3_256(head + _tail).hexdigest() == h:
        _b = True
    else:
        die(border, 'Your should pass the POW! Bye!!')
    kem = MLKEM_1024()
    c, n = 0, 1337
    KEY_PAIR = [kem.keygen() for _ in range(n)]
    SKEYS = [KEY_PAIR[_][1] for _ in range(n)]
    r = randint(0, n - 1)
    cipher, shasec = kem.encaps(KEY_PAIR[r][0])
    secret = hashlib.sha3_256(shasec + hashlib.sha3_256(shasec + str(r).encode()).digest()).hexdigest()
    while _b:
        if c > 3 * n:
            die(border, 'The server is need to rest :/')
        pr(f"{border} Options: \n{border}\t[D]ecrypt cipher \n{border}\t[R]andomize a secret key! \n{border}\t[S]ubmit the secret \n{border}\t[Q]uit")
        ans = sc().decode().strip().lower()
        c += 1
        if ans == 'd':
            pr(border, 'Please select an ID: ')
            _id = sc().decode().strip()
            try:
                _id = int(_id)
                _shasec = kem.decaps(SKEYS[_id], cipher)
            except:
                die(border, 'Your input ID is invalid! Bye!!')
            pr(border, f'{_shasec = }')
        elif ans == 'r':
            pr(border, 'Please select an ID: ')
            _id = sc().decode().strip()
            try:
                _id = int(_id)
                _skey = SKEYS[_id][:-32] + os.urandom(32)
            except:
                die(border, 'Your input ID is invalid! Bye!!')
            SKEYS.append(_skey)
        elif ans == 's':
            pr(border, 'Please send the secret: ')
            _secret = sc().decode().strip()
            if _secret == secret:
                die(border, f'Congrats, you got the flag: {flag}')
            else:
                die(border, 'Your secret is incorrect! Bye!!')
        elif ans == 'q':
            die(border, "Quitting...")
        else:
            die(border, "Bye...")

if __name__ == '__main__':
    main()
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃ .:::       Welcome to the Mechanic II cryptography task!      ::. ┃
┃ Your mission is to find flag by analyzing this amazing Oracle! :) ┃
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
┃ Please pass the proof of work first: (b'vf3ztJFHdjF3ASH', 'a1038345b7ce0217cd001266dc6504a65113a689a08c83230e38ddb3bcbd940f')
iuDJ
┃ Options: 
┃       [D]ecrypt cipher 
┃       [R]andomize a secret key! 
┃       [S]ubmit the secret 
┃       [Q]uit
d
┃ Please select an ID: 
0
┃ _shasec = b'h\x1deD=\xe1\xc2\xc4>\x14-#b\x1bQ\xebn\xb6\xab\xe4\xc2<\x02\xf4R\rg\xa9\x988\xa6!'
┃ Options: 
┃       [D]ecrypt cipher 
┃       [R]andomize a secret key! 
┃       [S]ubmit the secret 
┃       [Q]uit
r
┃ Please select an ID: 
0
┃ Options: 
┃       [D]ecrypt cipher 
┃       [R]andomize a secret key! 
┃       [S]ubmit the secret 
┃       [Q]uit
s
┃ Please send the secret: 
4376ce0637dd274174ea452a2dfe7862ce03393db71dc81e046a340cc353629a
┃ Your secret is incorrect! Bye!!

解法

この問題では秘密鍵の末尾32バイトをランダムなバイト列に置き換えることができるので、その32バイトがどのように使用されているかを調べます。 「Module-Lattice-Based Key-Encapsulation Mechanism Standard」という資料の「6.3 Internal Decapsulation」という章を確認すると、ML-KEMの復号アルゴリズムが記載されています。

復号アルゴリズムの概要を秘密鍵の末尾32バイトに焦点を当てて説明すると以下のようになります。

  1. 秘密鍵の末尾32バイト以外の部分を使用して、共通鍵の復号結果を計算する
  2. 秘密鍵の末尾32バイトを使用して、ダミーの復号結果を計算する
  3. 秘密鍵の末尾32バイト以外の部分を使用して、復号結果を再び暗号化する
  4. 暗号化した結果が元の暗号文と一致していなければ、復号結果をダミーのものに置き換える

これを踏まえて復号結果がどうなるか考えると以下のようになります。

  • 暗号化に使用した秘密鍵と同じ秘密鍵を使用した場合:
    秘密鍵の末尾32バイトの内容に関わらず、正しい復号結果が得られる
  • 暗号化に使用した秘密鍵と異なる秘密鍵を使用した場合:
    秘密鍵の末尾32バイトの内容から計算されるダミーの復号結果が得られる

よって、以下のような方法でどの秘密鍵を共通鍵の暗号化に使用したかが分かります。

  1.  n 個の秘密鍵すべてに対して復号結果を取得する
  2.  n 個の秘密鍵すべてに対して末尾32バイトをランダムなバイト列に置き換えた秘密鍵を生成する
  3. 新たに生成した n 個の秘密鍵に対して復号結果を取得して、元の秘密鍵で計算した復号結果と比較する

元の秘密鍵で計算した復号結果と末尾のデータを置き換えた秘密鍵で計算した復号結果が一致したものが、共通鍵の暗号化に使用した秘密鍵であると分かります。 また、そのときの復号結果が共通鍵になります。

共通鍵を元にsecret変数を計算することができ、 それを入力すればフラグを取得することができます。

#!/usr/bin/env python3

from pwn import remote
import hashlib
from ast import literal_eval
import string
import itertools


# host = '91.107.132.34'
host = 'localhost'
port = 11111


def select_word(b, nl, nw):
    return b.splitlines()[nl].split(b' ')[nw]


def pass_pow():
    data = conn.recvuntil(b')\n')
    head, h = literal_eval(data.splitlines()[4].decode().removeprefix('┃ Please pass the proof of work first: '))
    
    chr_list = (string.printable[:63] + '_').encode()
    for tail in map(bytes, itertools.product(chr_list, repeat=4)):
        if hashlib.sha3_256(head + tail).hexdigest() == h:
            break
    conn.sendline(tail)


def get_shasec(i):
    conn.sendline(b'D')
    conn.recvuntil(b'Please select an ID: \n')
    conn.sendline(str(i).encode())
    data = conn.recvuntil(b'[Q]uit\n')
    shasec = literal_eval(data.splitlines()[0].decode().removeprefix('┃ _shasec = '))
    return shasec


n = 1337
with remote(host, port) as conn:
    pass_pow()
    
    conn.recvuntil(b'[Q]uit\n')
    
    shasec_list_1 = []
    for i in range(n):
        shasec = get_shasec(i)
        shasec_list_1.append(shasec)
    
    for i in range(n):
        conn.sendline(b'R')
        conn.recvuntil(b'Please select an ID: \n')
        conn.sendline(str(i).encode())
        data = conn.recvuntil(b'[Q]uit\n')
    
    shasec_list_2 = []
    for i in range(n):
        shasec = get_shasec(i + n)
        shasec_list_2.append(shasec)
    
    [r] = [i for i in range(n) if shasec_list_1[i] == shasec_list_2[i]]
    print(f'{r = }')
    shasec = shasec_list_1[r]
    secret = hashlib.sha3_256(shasec + hashlib.sha3_256(shasec + str(r).encode()).digest()).hexdigest()
    conn.sendline(b'S')
    conn.recvuntil(b'Please send the secret: \n')
    conn.sendline(secret.encode())
    data = conn.recvall()
    flag = select_word(data, 0, -1).decode()
    print(flag)
$ ./solve.py
[+] Opening connection to localhost on port 11111: Done
r = 1265
[+] Receiving all data: Done (74B)
[*] Closed connection to localhost port 11111
b'CCTF{se3D5_4R3_!mp0rTaN7_3vErY_WheRE!}'
CCTF{se3D5_4R3_!mp0rTaN7_3vErY_WheRE!}

Solving Mitram’s equations? Time to row reduce your expectations... and your sanity.

問題の概要

この問題では以下のファイルが配布されています。

  • 暗号化に使用したSageMathファイル (mitram.sage)
  • 暗号化した出力結果が記載されたファイル (output.txt)

この問題では、 q = 2^ 8, v = 40, m = 14 がパラメーターとして使用されています。 また、特に断りがなければこの問題で使用する数は位数が q = 2^ 8 の有限体 \mathbb{F} _ {2^ 8} の要素とします。

この問題では最初に行列 G, H, S が生成されます。  G  v  v 列の行列で、成分の一部がランダムな値で残りが 0 の行列が生成された後、この問題で定義されているmakeup関数を使用して上三角行列に変換されています。  H  v  m 列のランダムな行列です。  S  v  m 列の行列で、 0 列目がフラグの文字を \mathbb{F} _ {2^ 8} の要素に変換したものになっており、残りがランダムな値になっています。

 O を零行列として、以下の式で表される行列が計算されます。

 \begin{align}
& \begin{bmatrix}
G & H \\
O & O
\end{bmatrix} \\
& \begin{bmatrix}
G & \left( G + G^ \mathsf{T} \right) S + H \\
O & \mathrm{makeup} \! \left( S^ \mathsf{T} G S + S^ \mathsf{T} H \right)
\end{bmatrix}
\end{align}

出力結果にはこの2つの行列を複数回生成したものが記載されています。

  • mitram.sage
#!/usr/bin/env sage

from flag import flag

q, v, m = 256, 40, 14
_F = GF(q)

def makeup(M, n):
    for i in range(n):
        for j in range(i, n):
            M[i, j] += M[j, i]
            M[j, i] = 0
        return M

def mitramap():
    _M = []
    for s in range(m):
        M = zero_matrix(_F, v + m, v + m)
        for i in range(0, v):
            M[i, (i + s + 1) % v] = _F.random_element()
            M[i, (i + s) % m + v] = _F.random_element()
        M = makeup(M, v + m)
        _M.append(M)
    return _M

def n2F(n):
    x = _F.gen()
    e = sum(((n >> _) & 1) * x ** _ for _ in range(8))
    return e

def embed_secret(msg, v, m):
    M = random_matrix(_F, v, m)
    for _ in range(v):
        M[_, 0] = n2F(msg[_])
    return M

def maketrig():
    return block_matrix([[identity_matrix(_F, v), embed_secret(flag, v, m)], [zero_matrix(_F, m, v), identity_matrix(_F, m)]])

def makepub(F, S):
    S = S.submatrix(0, v, v, m)
    Z = zero_matrix(_F, m, v)
    return [
        block_matrix([
            [G := M.submatrix(0, 0, v, v), (G + G.transpose()) * S + (H := M.submatrix(0, v, v, m))],
            [Z, makeup(S.transpose() * G * S + S.transpose() * H, m)]
        ])
        for M in F[:m]
    ]

F, S = mitramap(), maketrig()
P = makepub(F, S)

print(f'{dumps(F) = }')
print(f'{dumps(P) = }')
  • output.txt

長いテキストファイルなので非表示(表示する場合はクリック)

dumps(F) = b'x\x9c\xbdY\xf9W\x13[\x97\x15AP\x088\x80\x1a\x04\'\x14\x05DL\x90I\x05}\x8a\xf0\xc4\x10\x84\xc2\x01\x05\x04\x0c\x81 \x10(\x82\x80"*\x840\xcf\xf3<\xcf \x83(\x10\x10X\xeb\x9c\x7f\xacw\xc5G?\xb5\xbbW\xff\xe4\xb7\xb2\x92[u\xeb\xd6\xad\xaas\xf7\xd9{\x9f\xca\xa7\xfd\xc9\xe2>/\x8d!-S\xeb\x97\x9bVX\x90U\xf2O\x93\x92\x99\xe1\xafMI\xd7\xea\rZ\xfb7\xfa\xfc,Mv\x8e6\xe5\x7f\x1cJ)R\xd8\x8bV\xff\xeb\xf9\xb9y\xe9\xfe\xff\xc7\xf9\xff\x1eJ)\xf2\xb7\x17\xf7{\xa9\x82\xd4\xcbV\x9a\x14M^\xbaVc\xb0\xd7\xea\xa5\r{\xd1:!p\xff\xbe}T\x1b\x1b\xf3\xb7\xa3\xfd)\xfb}\xfb\xf69F=\xb8/\xec\xdbgE\xcb\xd8\t\xb2\xb2\xc6/\r\x9cy)Gk\x1b\x1b\xfd8\x02-\xefJ\x1f\x9a\xe4^\x1a\xe6At\x1c\xca\x7f\xf0\xdc\xb0o\x9f\x13WZ~\xac\xa8\xf3\x8a\x93\x1b\xe6\xb8\x14u\xff\xee\xe3\x07T\xcb\x9f\xb9\xe3\xda\x03\x9b\xb8#\\\xcd+\xb4z\x90\xc6\xd8\xe4A\xd3\xc9\n\xae\xa1Z\x1a\xe1\x8a\x085U\xa4r\xbb_\x82\xef\t2F\x911\x87\x96\xb9\'\xf7\x04\xcd\xdf%\xe3\xb3\x88h\xfb\x02\xee\xa3\x06\xde\xb9\xcb\r\xd4\xc7\x93\xd9\x06^\xa3FnP\x18\xb86\x9fv\xf9k)7\xf0\x16NY\xd0\xf0z`\x88\x07\xb5\xf1R\x0c\xad\xe4\xfc\x85\xcb\xf5\xd0,\xb7=\xa5\x06\x1a\xa4\x9e\xd2\'h\x8d\xd4\xc3\xfd\xcf\xb01O=\xb4%\xf54RO\xa2\xd4Q\x8d\x8ey\x17\x1e\xbf\xcdSg\x8ek\xfcy\xca\x0f;\xa1<EU\xc7i\xdc\xd5p\x85\xea\x94n\x86<\xfc\xba\x18\x92\xd9\x84\xc1\xcddVY6\xd6\x8a\x9e\xb2\xe9\xe1\xf5\x97\xbe\xb4\xceS\xfe\xbc\x15z\'\xe9)B\xd4\xc2\xf5\x98\xd6L\r\xb9\\\xcf\x8d\xd2F6\xd7\xe7\xd2&-\x94P\xa3\xc7#?\r\x0f\x14P=\x9a\xca\x82`?Z\xc5\x19\xfd\xb4\xc6\xf5\t\xb4l\xab\xa6n\xee\xe5uD\xb8\x17\xe7n\xd0W[\xea\xe4\xfa\x0f\xd4\xcc[\x8fb\x92\xb8\x8a>q\x07O\xbf\xe2\x91\xeb14I\x8b\x97\xe4\xf1\x02u;S\xc3!\x9a%\xe3!\x1co\xe3\x8e\xa7T\xc1\x9d\xbcD\x93z\xaa\x10}\xf9\xdb\x15.G8\xdanR_*}W\xf1\xa0J\xc1\x8b4Ak\xc7\xa8!\x99f\xaf\x1fz\xca\xcdiy\xb4\xc0\xd54\xcd\xdf\x9eci\xb7\xc3y\xcd\xdaIq\x8d\xb7\xa9\xdf\x83gK\xb1\xd2\xfb\xa2"b\xee\xd3\xe2\xbdTLi\x93`\x8b\x8e\x9c\xb4\xc2,\xbdR<P%\xda\n\xa2\x9d\xba\xca\xaa\xb6P<(\x88\x87~\xe0\xd5PX\xf0FS\xf8\xa6@\xeb\x97\x91\xa6)\xcc+xk\x9f\xa9\xd5k\x0b\xb24)\xff\xec\xa7\xec\x01\xd7^\xb4\xf7\xfa\xbf\xce\xc9\xc9\xcb\xcb~\x93\x9f\x92\x99\x93\xf7*-\xc7^tHp\xc0\x85#\xb3\xf4Y\x85\xda\xc8,mN\xba(3\x89\x8e\x82\xe8\xa4\xb2W\xd9%\x1c\xc0\xb1W\xda\xc2\xb4\x00\xf1p\xb5x\xe4\x9f9\x0b\xb2\xf4\x99\x06\xbf,}\xa16S[`\x9f\x9b\x96\xadM\xd9\xdb\x11\x8f& \x05\xf6\x85(\xc4c&\xd1Y\x10],\xbb\xefB\xc4\xe3&\xf1\xc4\xcfg\xe7\xe7\xe5\xbc\xd5\xe7\xe5f\xa5\xe5\xfc\xb4)%j\xc9\x8f\t\xb59\xda\\\xad\xbe\xd0^<\xf9\xff\x9f%\x1dC.\xea\x7f<k^\xc1\xbf\xf9\x1b\xfb\xdf\x83\x04\x8c\xb1\x17\xe5^:{/\x9d\x93\xee\x88\x97\xeeh\x82\x15\xee\xcc_t5\x89\xa7\x04\xd1\xcd\xb2W"\xba\x9b\xc4\xd31\t6\xd8F\xce\xeb\xc53:\xb7\x7f\x06*\xc5\xb3&\xf1\x9c \x9e\xaf\x89\x89\x89\xa9\xc1\xb2x\x94\x89\x17\n\xc5\x8b\x82\xe8\xa9\xc3I\x97b\xd0uY\x10\xbd\x92E\xef_\xa2\x94a\tl\xca/!\x93\xf8\xc4^\x8d\xaf\xe8\xa3;\xaa\xc3\xbcW\x04\xd1\x17[\xb8\x95\xab\x82\xe8\xa7\xf3\xac\x16\xaf\t\xa2B\xf7\xcfQ\xa5 \xfa\xeb,\xbd\xd7\x051`\xaf7P\x10\x83~\xf4\x06\x0bb\xc8^\xef\rA\xbc\xf9\xa3\xf7\x96 \x86\xee\xf5\x86\t\xe2\xed\x1f\xbdw\x04\xf1/\xa9\xd7\xf2L\n\xf1\xaeI\xbc\'\x88\xe1?\x8e\xdd\x17\xc4\x88\xbd3"\x05\xf1\xef\x1f\xbd\x0f\x041\xca\xd2\x8b\xb1\x0f\x05Q\xf5\xa37Z\x10\xd5{cc\x04\xf1\xd1\x8f\xdeXA\x8c\xd3\xd6\xd6V\x8bB\x95\x18/\x88\x8f-\x98\xce\xcc*J+\xc8\x13\x9f\xfcx\xc0\xa7\x82\xf8\xec\x9f\xcb\x87\x88\t&\xf1\xb9 \xbe\xa8\xb1\xec\xbe\x13\x13-\x81\x97\x16VL\xaa\x91b\x9c\\&\xbe,\x14S\x041U\x15\xa4\n*\x14\xd3\x04\xf1\x95\xce\xcaK\xf7\x0f\x01\xeb\xac\x13\xee\xfcA\xc2\r\xf9\x89piW\xb5?Mn\x97\x9f\xc5\xab\x8f\xa8\xc5V,8\x06>\xe8:\xc1\xe54\x99\x93\xaf\xb3\xa7\n\xea\xe7\x010qm\xf2\xc5b5UR\x85\xedy\xaa\xf8\xc0-\xe7l\x1c\x1d\xe3\x1c\xa9"\x16S\xb4\x81\xc3,\x9f3j\x90G9\xadS%\x8f\xdc8[FC\xa54D\xfd\xa7\xde\xf3\x08>[\xfc\x053U\x83\xae\x86\xf0]\xe4!\x97\xfc\x83\xf1<x\xdf\x0e\xdc;L\xf3\xb9\x06G\xae\xca\xcf0\xdc\x02\x85\x8fb\x9a\xa9{\xe0\xa7e\x9e+\xfc(\xe3\xa5 Pf\xa3<2\xe8Y\x067\xbc\xa0n\x1aH\xe6\x1e\x1e\xb8D\xc3\xb9:\xc3U\x8ck\xa1od>\x96\x92\xc8\xad \xe2\xba\xf7*\xae\xb0\xf0\xe2\nm\xf2\xf4-6\xfb\xf0 \x9bC\x94\xd4\xf7\xce\xea\x11\xb5]\xa1\x19\xd9e\xdc\xf4<Z\x15\xdaz\xb4e\\{\x9afeTO+z^\x0b\xf6\xe6E\xd5K-x\xb0\x05\xb7\\\xc7u\xdcB\xedI4\xe2\xef\xae\xa2\xc6D\xea\xa4\xd1K\x81\xbc\xe9\x13\x1e\xf1Z\xc6_i\xf7\xd6\xe5@n\xe3M\x1a\xcd\xbf\x1cH;\xe8Y\xe5\t\x84m\x8c\xfb\xef_\xe0\xa9\x83P\xa5\xc9\x84bE\x80\xf7\x87\x10y\x8c\xf7\x87\x9br\xee\xf2:\x13"\xa79\x17Z:-\xe3z\x97\x14w_\xd0\xfd\xcc\x01;6\xde\x86R,\x921\x8d\x06y\x0c\xb13\xf2(.?F\xabd\x8c\xb8"\xa7\xd5\xab\xb8\xd8\xa3\x007j\x0b\xc3\x15\x06\xb8\x91{\xef\xa4\xdf\xa1-\xea\x0e\xd6_\xf2\t\t\xfe\x8dz5:\xf0m\xba j\xd5=\x12\xdff\x08b\xa6\xee\x1f\xc0\xe9\x041\xebW\xc0E\xffA\xc0\x05\xff\xac\xf0*\x9b4\x8b\xc2;GS\xc5]^\x8eu\xa1\xfa\x88\x18j\xe7r\x8f\x83T!\xb7\xa1\xfaTn\xf5+\xe1%\xfeT\x94\x1a\xe2\x04i\xac\x88\xf3-\xa0\xb1TZ\xe1\x197jq\xf0\xb0\xa5\xfaKW\xa9+\x9c>\x9f`3\xcf\xd9\xf3&/8B\xdb\x17\xb8\xc1\x93\x8d\xea\x12\xde\xc0u\x9a>\xf0\xdaa\xc4\xd3\x93F\xa2\xe2\xb8\x93\xbeh\xaf\x17\xd3\x18u\\E,MP\xb4\xe9\x0c\x1b\r\xd7\xf24-\x1e\xd0\x00m\xd3TeC\xe3\xfc\xd9\xf0F\x92?\xfeB\xe64\x00\xb9\x87\xd7\xc9\x0cA,\x81\x930\x1f\xe7r9\x03f\xb7\xa5}\xf4?\xc3\xc8\r,\xb69\x8b\xcbC\xa43\xb4R\xdb\x8a\xe5\xfb\xce3!\xd4F\rJn,\xa3\x9eh\x04g\x98\x86p\xb1\xaflN&X\x94x,\xdc\xa0\xb4q\x12z\xdfH\xfd\x10dnt\x84Ch\xb0\xe3F\xb5t\xe0.\x0e|S\x03\xd8\xe5\xdcE\x1bJW\xaa\x7f\xa1acz\xb4kp\x80\x9c\xd7\xb1]\x9dN_\xe9+\x06\xccqm\x82\n@_\xa4\xf1\xb4\xebE\xf1\xefe\n\x1e\x12x\xe0\xb0\xc2)>\xd4AACBtb\xb1R\x13\x06X\x99\xf7\xc1#,\xf1*\xed~\xa4\r\xaaVR\xdb+O\xfe\xc4_\xc2o9!\xcf\x96\x1c\xf1lK\xd4g\x15y\x81M\xbc\x8a\xb1\xcf\xaeh\xb8_\xe4n\x1a\x0e\xa3\xcf\xee\xc5\xdc\xa9\x7f\x89dY\xa4\x1d\xfa\xcc\xd5\xefx\xe1,}\xb9\x86\xdc\xe9V \xe5\x8c>\x02\xaf\xff\x86\xbe\xd7\x12\xfa\xb2\x051G\xdd-\xa1/W\x10\xf5{\xe8\xcb\x13\xc4\xfc_\xd1w\xeb\x0f\xa2/\xe8W\xba\xa3\x8a\xb4#v\xf9\xbck\x95\xed\xe4v\x0cFq\xc0&KG3Q\xf9\xf8y\xce\xdd\xe7\xa8\xfaA\x92\x0f|\xd5\'\xac\x831\xe0\xd4=\xaa!x\xbb\xd70N\xb4F}\xc7\x10\x9cr\x1a\xd1\xe5\xeb\x181\xc3\xfaO!\xd1\xcbi\x1b\xdb\x9d\xc9\xc5\xd4\xc4\xa3\x8e\xd8\xdc*\xe3\xa1\xd2\xdb\xbct\xf8%m\xc8\xb9\xea\x8d\x13\x06\x8c\x01\xe2\xedg\x92\xa9\xb6\xec\xf4I\xde\xcd\x07$\xbeq\xad<&\x97\x16\xc1lE9hLr{\x89\xe7L\xf2\x13\xd2^\x8d\x9c6\x83\xa8[#;\x1bT\xcc\xcdr\x1e\xcaA\xec\x9b\x94I\x12\xf1\x85j\x12p3\xe6L\x0b\xf3u\x16\xf1\xda\x85+\xdc\xc4\xcb~d\x0e\xa7\xce\xb4\x98\x82L\x1f6\x82\x88&|\xd0\xfeU@[>\xe1\x91\x05\\\xed\xe3\xf0\x81f^\xd2\xeeu\x1ax\x00#\xdc\xfd\x98\xaa\xc0\x8f\x96AT\xc5\x1d%q\xae\x00\xdb\x04\xe6\xec\xe4:Z\xf6\x0b<&\x1dh\xe5\x0e\x1d\xcdE\x83\x8b\x86\xed|\x1c\xb8\x19\xe9S\xfd <\xd3+\x9e\x17B\xe4g\xbci1D\xce_\\\xae\x9d\x96\xd1\x92\x0b\xad\x9f\x96y\x83\xaf\xba\x9d0_+7\'&\xc8\xf5\xdeA\xee2O\xaa\xcb\x02\xb7\xf9\x00\x84\xa04\x1a\x8dD*\xcf\xa5J\xd4f\x97\xc33\xc5l\xe4\x91\xac\xe0\x0f\xd4-{)\xd0\x00l\xe5\xe8;\xaa\xa3\x05\x9ab3\xad\xb9"=V\xb0\xd0\xc6\xdbV<\xcd\xdd\xca\xc7\xd2\xf3\x1f\xe7\x91\xdf\xc0&J`+\x10D\x83\xbaK\x02[\xa1 \xbe\xd9\x03[\x91 \x16\xff\n\xb6\xd0?\x08\xb6\x1b\xff\x82\xad\x93VT\xfbE\x17\xbb|\xeaOv\xa7\x8a \xf0\x85\ts\x8c\xd0\xda\xc1\xbb:j\xc9\xe0\xee{\xb4\x1e\xeb\xee~/\x87\xea \xb8\xe7\xa9\xd2\xcd=\x89\xc6i\x94f\xcf\xbd\xf6z}\xf4\xe2\xc1\xf3n\x85\x07/g\xf1\xec\xb5#\xb4#B\x12\xcc\xb4U\xca\x9b/\xe1\xd6?\xf3X1\x99AC[\xc5g?\x14\xd3\xee\xd9\xe2\x93\x88\xec\xf0\xc9\x07oy\xe3\x8a=\xaf\xc6#h#\x12"6\xdf\xfaP\xe5y\x1a7\x00\xbf\x95<\xfa\x1cL\xb7v0<\x1e\xb1l\xa3\xca\xb4p\xb4_\xa0\xea\xa34m@\xa1\x82\x01/x:\x94+\xf2i\xc4\x90B\x95Y<\xed\xe6\x1c\x94H3\x9eQ\x11\x91\xd4\x81\x15\xeb1$\x03\x12\xa3\xd4ap\xb6\xb4M\x86\'\x96\xb6\xddp\xd6\x83\x8da\x12\x8fz\x84S\xb5\xc1\xda\xd2\xdbo\xf0\xe7q\xee6\xfc\x9d\xce3\x06j\x0cC\xe7\no\xdd>\xe6\xfa\x12\xf7^\x95\x90\x8e\xb5\x9c<\x15E\xad\xe7\xb9)\x90\xea<\xc2\xb9\t\xda\xda\xf8 <\x83G\xcb\xf2\\\xe5\xbc\x96\xfc<\x08\xdc4\x12~\xfcbv*\xcd\xe0\xa4/\\\xc5\x9f\xf2y\x9e\xeb>\xf2\x10}\xd2\xf1\x1c-\x86*\x15\xc1\x87x9\x03\x88\xc2"\xb5R+Xs\x14\x8a\xdd\xc9\xfd\xb6T\xa5~\xf6\xd25!\x84\xa7o\xab\xb8\'\x99k\xb1|\x9fA\xc5\x8b\xa1\xbc{\xe9Z\xc0\xb3\x98\x0b`\xfd\xe1\xcc[\xdcN\x1b\xbc\xb6\x9fV3\xc1\xcd]9\x11\xdcsXMk\x01\xd0\xf0\x81\xa4}4\xf8\x1b\xdaJ$\xb4\xbd\x15\xc4w\xea^\tm\xa5\x82\xf8~\x0fme\x82\xf8\xe1W\xb4\x05\xffg\xa8\xad\rh\xbb\x17\xe7b\x9bO\xd3H\xe2r\x1a\xbdK\x95\xaf\x8f\xf3\xd6\xd9\xd7\x85\xf9\x87|=N9\xd3(\x9b\xae\xba\xf3\xa6\x83=W"\x0e\xa3\xdc\x18\xe1\x8ez\xb7\x0f^\xa9\x95V\xce\xe9\xb2\xa8Vq\xc0\x9b&\x82\xb9\xe3\x08\xb2\xf7\x0b\xb2u\x15\xf2\xf6\xbd\x98\xbf\xbas\xd3s6\xe6\xbd\xe5a\x1e\xa7\xefgy\xe9%/\xaaS\xa9\xcd\x0f.dA\x80f\xa9\x10\xa8\xa5\xb7\xd0\x8f\x8d\x07\x92\xf0\x9d\xd7\x1a\xac4\xa8G\x97\xc9\x1c\xaa\xe1\x19\x86\x85\xb4\xd7p\x8d\x94\xba~\xa0\xaeU2\x9f\xd2\x84HGoj\xe0\xb1 \x9d.\x1a\xdd\x83\x14hd\x15\x0f\x85\x80\'\x97\xa0+\x9b\x12\t]E9<\x04\xfb%Q\x9b;w\x1e\x90\xfd\r\t\xdaz\xeaz\xc6\x93\xbb\x05W\xfdE$\xc0\xa4\x7f\xa8JR?\x7f\x1aP\xf9\xc5\xba\xc2\x88\xb5\xa5\xc2\xa9\x05 z\xe5P\xfa\xba|o\xc7\xa0\xc7\xd0\xef-\x1a\x88\xc0c\xcf\xc9\x8a\xa5\x01\x0b\xfe\xbc\x10O\xdb\xd4\xe4Xx\x82\x07SP\x01\x97\x83o\xaa\xddx\n\xc1)\xa7\xe5\xbf\xc1\xce#0"\xbcz\xe5\x96\xdc\xe7q\xe63\xf0\xeb\'^\x8ez\xc33\xa9^qaE\x8a\xd0X\xda~\xa3H\x8a\x0b3(\xdc\x85\xb27\xb4\xac\x0bB\x1d\xccS\xc5H\xcd\xe5\xbc\x08\xdau\xe0\x8a\x08\xdaI\x80\\6\\{\x8dg\\?M\xf5\xd9\xdc\xac\x0c}\xce\x03:j\xc2\x83\xad\xa6\xabx\xed\x11\x90\xc6\xbb\xaa@\xa57O\xf2\xf2\xdb\xdf\x80\xf6Q\x02\xda\'A,\xffAk\x15\x82h\xdc\x03Z\xa5 \x9a~\x05Z\xe4\x1f\x04\xda\xad\x9f5tE\xc5\xc6\xd8#\xb6\xbcl\x0f\xf7\xb2QT@\xab\x1f\xe9\x93\x93O\x88\x97\xd7\xe3#\'O\x1e\x87\xc7\x1fK\xa0\x81\x17\xdc\xf2<\xe7.u\xc7\xc4P\x85\x07\x92\xb7\x1f\xd4VO\xed\xf8\x18\x0f\xd2\xa2>\x86\xea\xae"\x0c\x8b\xf7\xbcy\x86\xa6\xe3 \x02\x93\xc9pN\xf3<\xe8\xc3\xdb\xd4\xf5\xfe\x1a\xaf\x7f\x00\xbcL\x7f\x15@ek=h\xc2\x97&NB\x7fv\xb9;\xa9\x80\xc7\xef\x17\xde\xbd\xe4\x1a\x0e_?E]h\xbby\xca\x03\xe8Y~mx\x8b*Bk8l\xa9"\x1a\xb0\x9cM8Z\xcbS\xb6\xae\x10\xb3z\x98\xa6\xd5c\xb4\x10\x82\xedJL>\xf5\x84\xaa\xaerm\x18\x9c\x7f.\x065\xa2u\x93\xea\x83y\x19WS[b\x9ck\xa4\'u\xbf\x07Dw]\x9d.\xa2\xac\x99\xf3\xe7\x81(\x80m\xd6_\xf6\x80\x8cJ\xea\xf4\x84\x91\xc5\xe4\xf7\xb4\t\xd4f\xcb\xab\x92`6\x06\xd0\xc6\xb3\xe7\xb8\xe7\xf5(d\xe2,\x808\x13s\xc0\x1a\xe4=J\xad\xafA.\x00W\x14\xc05\x97\x1aBc\xa7n\xc8\xfdh\x16e\x81\xfdc\xaav\x97\x95>\x86\x15\xab\x12i\x8e\xb6\xd0zpg8TS\xc6\x9deh|\xb93\xdbN\x95\x19\x96\x11\xc7Ke\xa1y\xe0\xd1vZ\xe3m\xfd\xd5\xdb\xe9\xa0E\x90:-\xf1\x82\r\xcd\xf3R\xf1-\x14C\xb8\xbc\x0c7S\x83$\xfe\xe6\x8f\xad\x13\xc5\xd4\x9f\x86\xc2\xeb\xab\xe5\x8d\x8d3\xaf\x1d\xe2U\xee\xf0CjU\xa4 5\xd6~\xc3]\x95\x84\xbbjA\xacQ\xf7K\xb8\xab\x15\xc4\xba=\xdc\xd5\x0bb\xc3\xaf\xb8\x8b\xff\x83\xb8\x0b\xfb\tw\xb7T\xd6qG\x0e\xf0\x08}s\xce\xc9\xf1\xb8K\x0b6Q\x99\xd4\x1a\x03\x1e\xf9\xc2\x1d\x82\x12\xd9<x\x84ZR\x8f\xc7\xfa\xf2\xb6\xb57W\xc2\xba%d\xd1\xf4+\x9a<\xc8\xfdY\xceG\xcfk\xdf\x07p\x17\xefP\xf9\x05$v%2\xb0\x195\xd4J\x0c\x88\xa6\x85\xdbQ>\x0c`\x95\xb6yM,\xe6\xa5\x0c\xb0\xd6\xa4\x15\x19\xaf\xc3\xc4!R\xc3j0\xc8\xbaF\x82\xfb9n\xb6b\xe3K\xeaK<,\xc7\n\xb4%\x9dQ\xbc\xa7I\x8b\x16\x7fJ\xf3\x07\x17\x1e\x90\xf1t\x16-\xba(\x92h\xf9\x02\xa4\xfa{\x1c\xd7\xc4\xa6C\xda\xfaq\xa75\x80\xc1\'\xd4\x0e\xb0i\xd4\x8b\xd2\x01"5J\xb5(2\xa4\x8er2{J-\xc8\x81w\x0e\xd9]\xa7!\xdd\x01\xb0\xa89]\x1f\x0e\xd8\xf7)\xb3\x03\x80\xd7\xa0l\xee@s\x12^m\x86\xe7\xe2\xf1\xec\xcd\xa7\xb0\xec\x9b\xd1E\tH\xb0I\xda%\xc9\xb9v\xd0\xd6Kp\xf50\xaf\x17]\xe1I\x9a\xa5\xf2\xb4{\\w\xda\x1a6\x00\xdc\xba&)d8\xd7\x85[\x03#\xbd\x18\xbc\n\xa1\x84\xe7\xea8-u\xf4S\xc7\x15\xec\xbbz\xd3\x92\xa3,X\xd0\x9fB\x1d\xb4\xc5[YrT(\xfd\x19\xd4]\xe6\xc4\xe3\xfeZDj\xd5\x856\x83aJz\n\x90K\xdb\xc1\xbc\xf96\x08\xb4\xbd\x83\xa4\x9c8\xca\xc6WTg\xf8\x88\xbb\xdc\xa6\xde\xd0(\x117Q\x83\xc7\x1a\xbe\xc1\xcdq\x88}\x83+\xad*\xdd\x8e\xf2\x9a#\xcd\xed\x0f8L\xa3\x8f\x9dx\xf77\x106J l\x12\xc4f\xf5\xa0\x04\xc2\x16Al\xdd\x03a\x9b \xb6\xff\n\xc2\x9b\x7f\x10\x84\x01?{\xba]Ie\xa5\xfa\x81\x8cA\xa7\x8f\xf1\x00W\xd0J\xfe\xf1\xd3I\xfb\xa9\xf5\x1c:M\xa7x\xdbA8r\xdf\xe6<\x8dy\xbfx\xe1hw\xd9\xd3\x0b\xeb1AU:n\x89;BC\x07-\xafTZ\xb8\x8f\x97\xa9\xf12\xd4f\x9b\'o\xc0\xf6\xaeR]f\xc9{^\n\xe3u6\x96\x9d<\xc3\xeb\x9e\xbc\x9cR\xcc=OT\x1fyL\xc3[\xd1\x08\x7f-7\xc4\x9c\x04\x03\xb7ru,\x84\xd6\x0c\x97W\xcd-\xc7 \x98\xd3\nZ\xd0\xf2"\xf7BX\xdbq`A:@\xd3O#!\\5\x99(\xf8&i\xc0\x80K~J\x8b$\xf3ET\x82\xcbj\t\x86]i\x11\x18\\\xa3\x95\xc7\xea\xb9\xc2\xdf=\x1e5F\xa5V.\xf8q\xb5\xff\xfb8\xa94\xf1/\xa4\xd9H\xae\xf4O\x8a\xa3F\x15u\xd1\xe8\xbd@}\x02U\x9d\x81b\xd6\xd0\xb2\xcc@sq\xa9\xae\xdc\xa4.\xbcc\x05\xa5\xee\r\xc6E\x9b\xf1\x84\xa39(x\xb6\xa8\x02\xb1\xad\xe7U{\xaa\nv~t\x9c\x1bh\xc7\x89\x86\\dY\xce\xb4t\\F\xc3\x97\xa8\xeb\xb8\xcc\xd1\x99\xfa1\x00(\xac=l\x9f\x013F\xcd\xf6\x19\xcf\xc22h\xf7]0\xd5\x15\xd3\x16\xa6\xdcz\xcb\xdf\xa9M*\xd8\xeb\xa8\xef:\xf7\xd1P\xeey\x91\xd7\xad$N\xe7\xca7\xfbqz#W\xaa\xad3x\xf7\x04\xe4d\xceV\x16A\xb5\x0e\x80\xf6\xa2\x13\xf2\xfa\x13\x92\x17q\xb6\xe2y\xfa\x1e\xe4\xf5\x8c*Jh\xe37\xacuHX\xeb\x14\xc4.u\x87\x84\xb5nA\xec\xd9\xc3Z\xaf \xf6\xfd\xe7\x84\xf6\xe7\xfaA\xf9\x03jY\xb4\xac\xa4\x8a{G\xe0ff\x1c`\xd6\xdb\xaf\xa6\xc1\xa0\x9d\x0b\xb0\xd7G\xd0<\x19U\xaa\x88\xf82*\xcf\x8f\xc9\xcf\xc2q\x97\xfb\xb4u.\x90\xbey\xdd\xbdK\xc34\x02\xa2+\xa7\xdd0\xaa.\xc6\xcanA\'\x06\xd9x#\x9b7\xce\xf2\x04nh\x91\xb6\xef\xf0\xf0\x13\x1e.=\x81Br\xea\x10\r\x9d9\xcb\x9b\xea\x97\xf6\\\xfeW \x004\xc9\x13\xcaW\x90?\x186LV\x93\x06\x96\x9c*\xba\x80`\xf7A+;=\xa8J\x95\xc5\x93E<\xe5\x95\x01\x9a\xea\x02\x7f~\xc6\xfa|\xe1\xf64\x9e\x93\xa4pT\x92X\x1f\xae?\x9d\xc8\x13I)\xf4\xe5\xbc\x05\xb0;\xdct\x9aksy\xd6\xed\x1d\xac\xde\x80TmZ\xcc\xfa\x00P]\x97\xef\xa3.D]\xea\x96\xc5c\x11Zx\xd0o\xdc&<\xe7M(\xdaJ\x12\xcdD\xd3N\x1e\xf7\xfb\x84S\xed\xeb\xb0\xeb4z\xdd\x85fo\xdf\x90G>\xe6nwY8\xcd\xa58I\x7f\xc2\xcc]\x87\\Zs\xa7\xb5\x9d\xc3G\xaa~fy\xa9\xd6\t\x8e\x95\xde\xa5\xb5\xa3^\xd8\xb2lU\xbe\x96*y\xde\xf1cc@\xa6\xd3\t\xd4\xf8\x03\xa0\xe7Z\x94\xe5\x9f/g\xbaA\xbe\x07\x93\xf1$\xb5\x99\xc8\x94\xbaW<\xa5\x83\xe0\xf6F\xf3n\xf6U\xae\xcaA\xf1\xfc=Cv\xeb\x04w\xa7\xcax\x1dM&\xfc\xc2\t\x94\xeeu`\xca\xef< )F9\xf5\\Q\xd1Z:\x16\xbd\x92\x1b\xad\xe2\x0e\xfb\x92\xa9\xe4q\xee\xa5\xdfp\xd7/\xe1n@\x10\x07\x7fT\x12C\x828\xbc\x87\xbb\x11A\x1c\xfd\x15w\x8f\xff \xeen\xfe\x8b\xbb\xf6k\x0f\xc2QH\x80!\x80/g$mE\xd6+\xb0\x8b,\x9a\xd6\x8e\x93\xc9\xd5\x06\xde\xa8\x8f\xcb/\xd9*e.\xa8\x10:\xc1\xec&\x92b\x89\xd4\xe4\x119h\xbe\xee\xdcA\x18\xdeZ\x1a\x11/A8\xfa\xf0\x99F\xb1V\x01\xf4m\x97\x16\x81\x8f\x9a\xa0G_\xac\x0f\xd3N)7\x83\xfeV@[[\x86x\x80u\xf3\xaf\x04n\xce\xc9x\x0c4\xb4\xa2\x12\xac{D\x0b\xd1/\xd8\x94}\x07fi\x9d\xcc\x85(\xfd\xb2\x0c\x10\x94O<\x1a\xf1\xe2y\x0c5\xdc\x03\x16\xbf\xf3\xc4\t@\xc6\x0e\xe6~\x10\xf6^2r\x9dO\x82xG\xe1\x8c\xec\x98\x82cS\xf1b\xacV\x02h\xd2\x13m\x08@6@URm\xe1I\xe6\xb7P\xdb\'\xaf\xe9;\xcdG\xf3N\xcaM\t\xb3\xe5\xdc\x01\x02\x99\x97\xa9\x04\x1e\x8f\xd7\x96P\xe7\xa9R\to\xaf\n\xb8\xfef8N\x1e\x83\xc8\x02\xd9wq\xd7\x08B\xbeJY\x04n\x9f\x02T\xa0\xd3\xa8\x05\xf8{,\x7f/\x8d\x80|\xde\xa0\xba\x93\xc0\xa3\x8cM\xb9\x80\xe0%\x18\xb1\x05\x0b\xf0j0\xc5\x984\x85\n\xb9\xb0\x98\xca+>\x119P\xcc\xa5"L\xbc\x15\x08\xeb\xbb\xe8\x9c\x0b\xe0\xa3,\xe2/~\xcaSw\x12\x11\xd91Z\x94\xe3\xde\x9a$7\'m\xa06\xe3A\x05\x9e\x1d%]\x99\x92\xa4\xd7\x84&-|n\x13\xca\xb0.i@;Fn+\xe1\x8dg-\xefO>r\xc5\x07\xab"2]\xd3\xf3T\x04\xe4\xa1\xf57\x14\x8eI(\x1c\x17\xc4\tu\x9f\x84\xc2IA\x9c\xdaC\xe1\xb4 \xce\xfc\x8a\xc2\x90?\x88\xc2\xab?\xa1P\xe9\xf5w\x9c\x8b\xf4\xa2\xf8#\xd7\x9d\xa3\xc9\x8bdt\x89x\xeeM\x93\xbe\x19\x92I\xd9\x95\xd1\x04\xba\xb8\xe1\x92\xf3-\xf0S\xad:\x88Fc?:{z:G*\x9f\xf3g\x01\x19<\xe7\xcdM\xa50`;\x86\x9b\x99\x80\xe9n0\xb0\xb6x\x0b\xf2\xdaN\xdby\xb4\x11X\xe0J#\xd4\x93\xe6C\xab\xd60\xe4\x15$\xf1\xdd\\\x19~:T\xd4p\x81\x86\x13}\x95\xb4\x89\x8aa\x90\xbb\xc9\xf4\x84z-oY\xcdO\x11\xdcV\xac\xa0\xf92\xb5+Q\xf1\x9a\xffF@W\x00\x013`U[\x82\x0b\r\xf0p\xd8\x15W\x00\xb6\x8f\xfb\x03\\\x0f\xa3\x99\x0fp\xbdL}\xa5JW\r@3\xc2\xed\xe9\xefu\x04\x0b)\x9d7\xe7\xa8\x8f\xe6*\xd8\xba\x92 \xd7g\x10\xb6\x11nN\xcf\x89J\xf6\x96\xe5\xa0w\x02`\\\xdd\xc7\xe3\xf7xN\x07\xd0Ors\xe2A\x05,\xd5\xe4\x19\x1by\x98@\xd3\xd6\xd4\x10\x8c\\\xda}\x84\xea\xc9(\xa7\x8ew\'R\xe9\xab*\xccQ\xe1D\x93A\xfb%\x935\xcb\xfdV`\xe6fi\xb6*\x1e\xd3{\xdc\xa2\xcfw\xc0\xfb@,\xd2\x02\xd9\xd8\xe5\x80,\x19\xfe(\xfd;\x83\xa2\xa1\x1e\xf2\xb2\xc2\xf3b\xe9!\x1eG\xb5>\xce\x8b\xce8q\x80\xab\xdf\\\xa6\x06\x91\x9a\xdd\xa2\xa8\xe7Z\xb1w6\xaf\xc2Q\xd4\x9d\xa4e\x9e\x10O\x1fr\xc0\x8d\xd6\xe21\x17 \x12\xcby\x0f\xb9_\tN\xf8\x86\x0c\x99\xe2\xfa\xdf\x906+!mN\x10\xe7\xd5\x8d\x12\xd2\x16\x04\xf1\xf3\x1e\xd2\x16\x05q\xe9?\xf7\x9eN\xf1/\xd2Zi\xe9\xd1\x8f\x97\xc2\xb0T\x83\xe9\xe7\x8f\xeal#\xd3m\xc8h\xc3\xd3\x17Cx\xe2N*\xefx)\x82`j\x1al\x0c.dts\x81S\xc5\xda\x99\xd4\xc14w\x91\xc6\xf1\xe8+\xd4\x1b\xa0\xe0^\xb8\xba\xd9s\xd0\xb2\x1d^\x0c,\t\x05\x0e\x16\x8b\x9e\xb9R7\xf6\x9by\xf16/\x19\x00\xc6!9\x96c>,\x84M\xe7\xb8#\x95\xbe\x05R\xf7%6>\xa4\xcf\x1fx\xe5>\x8c\xe2\x00\xcf\xa2L\xed\xb8x\xd2\x97+x\xfd#u\x80\xaev\xa4\n\x85:\x93\x9eiu\x0fx1R\xcb3h^j\xb1\x04-I\x82\x96f\x1e\xea-\xef3\x1e\x02\x9eh\x07\x1eRc<u\x9e\xf7\x0btB\x9d\x00\xda\xed\x80S\x9b\x95\x05\x02(+4\xe9\xcf_\x11\x9d\xaa\xfb\xa0\xb6I\xde8\x11PHU\xa1l\x92$\x13\x97\xda\xfb\xcb\xa9\xfe\x95Dn\n\x1a+\xe1\x85\xd4\x12\x1a\x052\xc6\xa5zU\xfag%\x15\x97\x956&Ruq\xf4\xdd\xa0x\x1f\xcb\x0b7\xe5\xb7\xbdi\xeat\x0e\x99\x9d<P\x13-\xd3VIa"8j\tL\xd5Jm\xc8\x9f.\xae\xcd\xc8\xe7M(\xe7:*s\x13wJ\xe5\xb8\x91M"U\x19 \xb1\x0b\xd75\x98\xf6+m\x9c\xd7x\xbd@\xe0v5\xdcj\xc8KL\xa2f%}\xbd\n\xbcV+/\xfa\xea!E=X\xafm\x1fL\xd1\x9b\xcd\xc6\xa0\x1c5\xf7\\+\xa3\xae\x00\xc7b\xd4\xfa#4\xf1\x1b\xda\x96%\xb4\xad\x08\xe2\x17u\x8b\x84\xb6UA\xfc\xba\x87\xb6o\x82\xb8\xf6+\xda\x82\xfeC\x15\x84\xf2\x9aM\x9c\x8bT\xc6\x8e\x82\xe4G\xb8\xff~8\x95\xe7\xf0g\xbb\x07\x07}\xa8\xf3\xfe\x85\xf3T\x19\x13\x0e\x93\xd2\xc9\x8d\x19\xce\x07\xc8t\x1f\xbcT\xf5\x88[\x84\xd8CT\xfb\x90\xc6\x04]\xac\x03M\xeaB\xa8\xe1\x15/\x95\x96\x1a\xf4\xbc\x98\xab}\xf4\x06\xb5\xfd\x00\x9b\xfd\xafC\xfd\x1a\xa8\x7f\xffs\xc4\xac\x8d\x87\xac\x91\x95[X\xaeq\xfe\x14z\xcb\xe0\x9f\xf8\xc6\x9f\x1a\x14\xc1\x1a\x80E\x89Bp\x88j2\x12\xd2\xa0\xbeU\xe9\xb4\xf1J\xcf5\xe9r\r-\xc6zr\xfd\r\xc3\x1bjOCEh\x16Aw\xa3R\xe9v@\xea\xe8s\xbc\xad\xa6\xaa\xe7A!\nW\xa0\xb2\'\x95\xeb\xd3y#\x95\x8c\x89\x96Q\x83\x8e18\xea\x00\xa0}\xcbI\xbd\xee\x1b\x95|X\xe1\xfe\x90\xb7\x9d\x14\xfc\xf5a\xae\xad\x1cJ\xa9\xb7\x91\x03\x92\x93\xb4\x96r\xdaN\x85\x9a\xb6\x9f\xbb\xf7\x01\x08#(i\xb0\xb1Uv\x15\xb8\xeb\x95)\x92\x1e\x969(\x1eCX\x9bl\x13\xa8\xef)\x9ei\x93\xc7\xf50\x81\xdf\xb9O\xc4sJ\x7fP\xf4\xbb\x03g\x03H\xba\x9a\xa7\x1f\xb9\xb9\x88\xc7D\xee\xa7\xba4t\x8cs\x93\x0b\xacW\xd6\x05$R\x9d\xe5\xbf\xe4q\x9a\xb3lI\xc7\xd6\x8e\xe3\x82}\\\xad\xf6\x924\xba\xb9T\x90q\xf7\x19 t:\x016s\x0b\xb6\xb8\xf7\x89/\x0f\xa6\x97\x9c9n\xa0i\xcb{H\x0b\xad\x9d\x95\x18\xde\xef\xbd\xf4R\xfb\x148\xf9W\x9c\xadK8\xdb\x10D\xf3\x8f\xeaaS\x10\xb7\xf6p\xf6]\x10\xb7\xb5~\xff\x05\x1c\x17\xab\x9a'
dumps(P) = b'x\x9c\xbc\xbcWW\x94[\xd7-\xaa("IE\x10T\x14D\x04\x0c\x04\x01%H2\x80\xa8$-\x94 \x02\x02\x92)\xa0\xc8\xb9\xc89\xe7\\\x80\xe4\x9c3U\xad\x8dq\xbb\xaf\xf7\x1f\xd8m\xb7\xdd\xce\xcd\xb99?\xe0\x9c>\x1f\x96\xdf\xf7\xaeu\xcen\xe7\xea\xfd\xdajK\xa0\xea\ts\x8e9F\xef}\xcc9\xe6\xac\xd6\x8aU\\x\x9c\x94\x9f\x90\x9a\xec(O(\xc8K/\xf9\xebG|j\x8aKr\xfc\xaf\xe4\xec\xfcd\xbd\xc2\xec\xdc\xf4\xa4\xcc\xac\xe4\xf8\xff\xd7W\xf1E\xcf\xf5\x14\x17\xff?\xef\x97\xe7\xfcr\xf9\xdf\xdc\xff\x9f_\xc5\x17\xb9\xe8)\xb4\x1e\x07\xb9\x85l^L\x8aO\xca\xf9\x95\x9c\x94\xaf\x97\x9c-~\xd1S\\\x8a\xd2\xd3\xb9p\x81Z>\x87\x06\x1a\xea\xdd\xd5\xbbp\xe1\x82\xe1\xc7\x0f\xfe\xb2\x0b\x17.\xd2&\xfep\xbbx\t\xff\xd2\xb8E\xdcm\xfc\xbc\xf29\xf8k\x00~\xb2F\xfcGs<B*\x9e\xc0\x07\xba\xb9\x1f\xa2\xf3/\\\xb8\xc6\xf5\xd2?\x17i\xe0\xd95\xf3\x0b\x17.;|\xf4\x7f\xf3\xf5\x03\xb5$\xf1!\xab\xf8\x84T\xb7y\xd3\x9d\xb6y\x9f{b\xa3s\xb8E\xeeJ]\xbck\xc9=\xf8\xbe\x817\xc5S\x8bh\x86w\xd3i\x894\xac\xa2\xb3\x87\xcf\x14\xa9\xdc\xce[\xdc\xf7\xd4\x92\xd4\x97h\x8f\xcf\x9cl\xdf\xf3\x18\xef\xd2\x94W\x00\x0fq{U\x9an&-\x068\x16\xeb\xa4\xf3\t\xab\xfc\xa9\xde\x8d\xce\xf8\x90\xaay\x8d\xc6\xde\x06\xeb\xd1Y\x99?\x9e\xb5\xa2\xd4\xca\xe4\x13%U\xd3&\xed\xfb\xf1t$>k\xa0\x11\xf3J\xfc\xddq\x8d\x97\xf1\xc8e-\xb4c\xdf\x8fzh\x8a\xf6y\xb5\xfc\xa3\x1fm\xd0~\xac\xa1^9\xed\x91\n\xaf\x9ey\xfa\x15\x97i\xa8\x8d\xeai\x97\xb6\x94EF\xb4\xc23x\xdb\x19\xcf{\xd3\xef\xcc\x0f\xb4\xfe8X\\\x91\x7f\x99v\x9dE\xb3\x15\xd4\x96\xf9\x14\xfd^\xe4F\x07\xdc8K\xfb\x96\xb4\x8e\x86i\x9eV\xc9\x9d\xa8\xfe\x1e\xed\xb2*\x04\x0f\x18~\xc1\x07<T@5\x9f\xf2\xf1\xec}\xd6\x98\xf3V\x861\x9dr=L\xd5\xc4x\x9d\xd5W%\x9e<M\xa7\xf4\x9bF>\xf0(\xab\x83x\x8a\xfb\xf0\xf5\x06\xeehx\xc3\xfb\xd4\x91\xc2u<h\xfa\x91\xda\xbe\xe1\xc3\x1ea+w\xdc\xfa\x9b:`\x98\x13\xee\xa55^\xe2m\xea\xe4\x8d`\x9a\xa4q\xde\xf7\xc8\xa2VX{\xcd\xcf.[N\xc7\xc6\xbc\xc6\xe3\xd4\x97\xc3\x1d\xa4\xbaA\x07\x11\x91\x99<\x98\xfcU\xce\x9a\x10E\x06\x8d\x99V\xf1,\x1d\xd1\x06w\xe2\x81C_\xa8=\x8c\xbah\xfdC\xa0hB\xbc\x0e\r\xd1\xfeO\x1eI\xcdF\x93[\xaf\xd1\x963\xafrK@\x10\r\xc2*x\xb5\xe6*5\xd1~)\x06tA\x9bZ_\xa4\x93\xfa\ti\xd0\xbe\x15\xea\xa6\xbd\x07\xd4\xe8\xf6\x83\xa7Ki=\x8f\x0e^s\x0b\xaf{:\xd0\x80c*\xb5\xf1\xdc\'g\xd1\x0b\xbc\xb5\x8e\x96\xd1\xbc\x11\xaa\xe1\x99\xfb):\xd4\xe5\xe0\xe9\xc1{\xd4\xc0\xf3|\x14\x1f\x05+\x9eq\x17\xae\x99\x87i\x87y:\xb3\x905\xd6\xf1\xa5\xf1\xdfy\x92\xfb\xbc\xec\xa8=D\x0c\xca\xbb(\xae\x97\xb1Z\x0fM[\xc0[&\xb9\x8dw\xb9\xd9\x13\x9d\xea\xe0\x81+\xb4"\xcc\xee\xf4\x9c\x1aJ\xac\xe9\xd8"\x9e\x0fh\x8d\xce"\x15a<\xf5\x83\x8f=q\x930y"5_\x0e\xe1\x01\x8c\x02F\x82\x07\n\xb9\xf7=\xefp\x13\xad\xf8>\xc3htc\x10T:\xb1<\x85\x11]I\xc2[\xe6\xef\x90\x9a5\x9f\xb8\xc1\x9e\xba\x94/\xd0\xc09Ck\x18a\xdd\xf7\x9e;/8\xf2\x98\x19\xaf\xf0\xd2\x13w\xeaE/\xc7r3\xf8$\x87\x1a\xb9\xf5V47%=\xf2*M\xe6\x1a\xea*\xa5A\xee\xban\xcb\xbfy\x90\x1a#h\x92[B\xdcy\xfc\x17-S\xdf\xcf|^\xa4\xea\x0f\xbc\xe7U\xea-Z\xa7|\xcb\xf34\xeb\xe3Lm\x914\\\xe9\xcd;\x05\xb8k9\xd6\xcc\x92\xa7%G\xd1\xd8\xde,\'uN\xc8\xa5p%\xcfr\x9b]8\x8f\xb0*\x00F\x9c\xe2\x01\xd1r#\xae\xf1\xce\xe7\xc6 \\:U\x01W\xe9GH\xd6\xc0\xc2\xcb\xf8w\x14\x11\x85\x91\x88\xd7JU\xb8\xe8\xb0*\x14\x9e\xa8F\xbf\x0f\xe1O\'4\x83\xa1\xea7\xd6\x12m\xc8\xe4\xea\xdbNT\xebF\xa3p\xb0a\xee(\xc6\x9b\xe7\x110\xd3\x18\xa3\x81\xe0\xb7\x92\x11\xdf\xa4;\xf1@9\x9f\xd9<\xa5V\xc4\xc6\n\x8f\xf3d\xce+\xaa\xf1\xfb\xc0\xd5\\\xad\xfb6\x844\xb7\x1eg\x00%\xd6\x83\xe1\x9fC\xac\xbe\xcb=\x9f\x95\\\xcb\xa34\xc5s7\x11\x94k\xdc\x08\x8f\xdb\xd3)\xce\xa1\xf1\x1b\xdc\\@\x8b4FcW\xe1\xab\xa9\x08\xf0f\xc4d\xb5~<\xd5\xd2\x08w\xf9\xd1\xb0K\xc0O\xee\xa33\xc7\xc4s?\xb9\xcc3|\x8aHi*\xa6\x1d\xda\xb3\xe0~\xda\xfd\x02\x1f\x1d\x06\x10\x1cQ\xe7c<\x04\xa0v\x86\x7f7,h\x95v\x7f~\xe1%\x1a\xa1\x89\x1c:)\xb8\xcc\xcb\xb4i\xf2&\n\x06Yb\xcd5RyS\x1f\x1cn\x10\xf6k@SWxU\xb7\x98\xc6\xfdE\x9c\x03\xca\xe6\x82yB\x0c\xe9Yf%l\xd8VFg4U$\xf3\xa0-a\x05\x1e\xa3z\xee\xe0\xc5\xd8\xbb\\K\x07\xb9p\xdc\x8eP\x18t\xff\x1a\xac\xb9\'\xbd^\x8d\xcb\xd6\x00"\x9d\xf6\xb4\x13\xed\xc4\xab\x88\xd9A\xe3P\x9b\\\x18\x01\x11\xc5\x8b\xdc\xe1\xcfk\xae\xdc{\xffa%\xef\x19\xa3\xd7C\xdc\xe8\xcb;\xd4\x8c\x00\xdd\xe4n\xaa\xd3\x0b\xb2\xe5\xbd\x00\xaa\xcf\xbbp\x93\xbb\x7fq3\xb5#d:\xed\xddx\xcd\x85\x86\xbf\xd11u\x96\xc8\x9f\xd0\x98-\r\xd0\xa4{\x02\xfck-\xcb/\x1a\xc0\xda]"\xbf\xc7\x9a0\xf4\xf5\x94\x9a3\xcax\xdb\x9ew\xa3#\xb4\x00\xc2\xa3\xb4\xef\x86H\xd8.\xa9(D\xf3\xba\xd0\xe5V>\xf0A\xef\xeb3\xa9\x8f\xfb?\xc7\x14y\xc4\xd0F\x11\xb5\xd0\x90\x1b\xaf\xbc\xc48\xeca\xacZ\x9d\xa8\x9d\x06>\x01\x16\x1dmx\x0b\xb7l\x98\x89o\x10F\x07\xbc\x96\x0c<Z5K\xbc\xc9\x13J>\xe2\xcd2\xf1\x8d6O*o\xf1J\x02\x9fF\xf0\x10\xfd\xe6\xf6r>y/\xbeH\xa6qR\x17\x7f{\xf4\x84\x16`\xbf\xd3\xa7h\xcb\xc1\xd7\x9bbX_\x02\x8d\xd0\xba\x14\\=\x9db\x08\xbb7T\xa0Q\xfc\x1b\xce\xd2IC\xf1\x99?0\xe0\xdd \x98Y\xd8\\\xc3c\x17B2\xb9\xfd\xfe\x07\x8c\xdd\xf67\xd0\xd7\x85\x8f\x01\xa1\xfe\xb4\xfe\xf6\'\xd5*.G]\xc1\x07Y\t\x05\xe9\xd9\xce\n\xedF\xc5\x15\x99B\'\xa4\xe3rK\x81\xe2\xaaL\xa1{N\xc2\xf9\x05y\x85I\x05\x85y\xc9\x8e)\tI\x059y\xa5z\xa9\xc9\xd9\xc9y\xe9I\xf1\x7f\xfd\x1d\xff\x87\x8d\xf5\x14z\x8f\xffw\xf7d\xe5\xe4d\x16\xe6\xc6\xa7f\xe5$&d\xe9)\xf4\xa3\xf4\xf1\xe2\xf7\xe9\xd9\xe9\x05\xc9\xef\xd3\x93\xb3~)\x0c\x1a\x14\x862\xc5\xb5 \xbd \x9d(m|\x97\x98\\\x90\xf0Bq\xbdIq\xe3\xafg\xe6\xa5g\xa7\xe6;\xa6g\x17$\xa7&\xe7\xe9\xc9\x132\x93\xe3\xff\xfc\xa10\x8a\xd2\xc2-\x1e\xcf\x157\x1b\x14\xc62\x85\x89\xf4g\x99\x87\xe2V\x83\xc2\xf4_\xef\xce\xcd\xc9*\xcd\xce\x91\xa7\'d\xfd\xcb\xafB}\x94\x9c?09+Y\x9e\x9c]\xa0\xa70\xfb\xff\xbfK|\x07\x81\x91}\xde\xd7\x9c\xbc\xff\x14%\x9f\xff\xe3"\x19\xae\xd1S\xdc~\x9c\xa6\xf78\xedZ\xda\x8d\xc7iFQ\x17\xd12\x17\xc5\x9d\x06\xc5]\x99\xc2\\\xfa\xabDq\xafAq?4\xea2~\x87\x90\xc9VX\xa4\x99\xffu\xa1\xb3\xc2\xb2A\xf1@\xa6\xb0j\x0e\r\rm\xc6\xb0<\xacTX\x17(\x1e\xc9\x146i\xb8\xc96\x14\x1f\xd9\xc9\x14\x8fc\x15O\xfef\xa5\x14\xc9\xb0\xf1\x7f3\x99\x10Iz!\xf8_\xf14\xcd(\r\xcf}&S\xd8\xe374\xc5A\xa6pL\xb3iR8\xc9\x14\xcf\xd3\xfe\xfa\xd6Y\xa6pI\x93>u\x95)^\xfc\xf9\xf4\xa5L\xe1v\xfe\xa9\xbbL\xe1\xf1\xe7SO\x99\xe2\xd5\xf9\xa7^2\x85\xf7\x9fO}d\n\xdf\xf3O\xfdd\x8a\xd7\xe2S\xa9O\xcf\x15o\x1a\x14oe\x8aw\xe7\xdf\xf9\xcb\x14\x01\x7f\xeex/S\x04\x9e\x7f\xfaA\xa6\xf8(}\x8ak?\xc9\x14A\xe7\x9f\x06\xcb\x14!\x7f\xae\r\x95)\xc2\xce?\xfd,S|IniiR\xc8\x1a\x15\xe12\xc5W\xc9\xa7S\xd3\x8b\x12\xf2r\x14\xdf\xce;\x18!SD\xfe\xf5z\x0fET\x83"Z\xa6\xf8\xde,\xfdY\xa6\x88\x91\x0c/\x06V\xf1\xa3Y\xd88\xb6R\x11W\xa0\x88\x97)~\x06\xb9\x05\xb9\x15(\x12d\x8a\xc4\xb4\x8b\x8f\xd3\xfeR\x95i\x97\xa2\x8e\xae\xfc\xfbT\xe4\x83\x7fQ\x91\x1a%w*\x13\xb9\x9a\xda\x0cs@\xbd\xc7^\xa0\xf6cj\xa0e\xafR\xeaT\xfe\xba@\xad\xc1\x8f\xde\xd3X\x08\xf7\x82\xe1\x9bh\x0c\xf1>\x06.1\xb6\xcc\xca\xa2\xb6+\x90\x88\x10\x1e\xadW\xe5\xe0\xcfeH\xae\x81b/;_?<\xe7\x94N\xcd\xca\xafGI\xf2n\x07\x82\n\xe8\xc4\'W\xefeU9\x03\xd5w\x01\xf8\xda\xc0\xe2&\x1d+\x01\xdd\xe57A\x8d\xfbt\x98\xcd\xadx\xc8RN(\xb7\xa7\xf0\x1c\xc0r\x1b-\x19\xbe*i\xc4@!\x11\x01v\xf3\xdat\x9aU\xccSN4\xe6\xa1\xe4\x83H\\\xb7\xf3\\P\xcc\x861w\xdb>\xe0\x83,^\x80\x04[(\xf3\x85>^\x95\xdb\xd2\xf8\x0fny\xfd\xfa\xe5=:\xa4}\x88\xa6F\xee\xfc\xa1\xf0\x04(\xcfC*\xcc\xde\xf0\xb5|$\xcf\x844\xe4\xb1;vt\x04V\xdbE\xdb\xbb\xc1\x0c\x03\xe0\xd8\x06\xfc\\\xe4y+\x1e+\xd2#\x95\x1b/=\xbb~\xe9^U\x1ao\xcbS\x8b\x81\x82#i\xd4\xc23\x1f\x84V\xf0\xa5Q\x1d\xde\xf0\xb4\x05A\xee\xd0\x00\xb8\xa7\x1f\x0fh\x0c2EwT\xf7\x14Pl\xc5 \xa7i\x08\xaf\x06\xfdL\x82\\\xf2\xe3e\xe3(\xe8\xbf6\xd3G\xca\xdc\x0cj{\x1e\x91\xc0-\xa0\xdcYV9G\n\t\xc0\'\xf1U\x829`\x84\x86 \xf4\x7f\x94\x1b\xec\xf0\xf7\x1a\xc4\xce\n5\x15\xb9\xd3\x0e\xab>yQ\xb3\xd1E\xb3\xdc4\xee\xfb\xca\x87\xd9\xc5o\xb30\x183\x10E\x9a_v<\\\x98\xc0\x8d<&\xc4\xd9h\x81I\xf1\x13\xfc\x1c\xa4\xcd\x1c^\xae\x8c\x00H7\x7f\xa7j\x1b:6\xa4\xcd\x0c\xaf\xb2\x08\xd9W\xd8B\x8d\x0c\xa1.\xdc\xcb\x16\xa3\xbcI\x13T\x0b\xc9\x98\x05\xb1;\xcf\x1d\x0f\xa9\xd6\x8e\xa6\x15<\x07\xef\xda.Ou\xa1\xd1\x149\xbe\x19\x85Egi\x0b\xf48G\x13\xdc\xf7\tzXC3\xcfy!\x15\x1d\xeb|\x12\xe7\x06\xb9\xd2\xf7\x88\x06s\xc1ska\xd4\x8d\x91\xd2\x90&\x85\x8f\xb2\xc0\xff]\xb4z\x93;<\xa87\xef*\x86\xa4\xd9\x1b\x02`C\x1f\xdcrV\x90\x17\x07\x1e\xdc\xe7\xf9\x9b\xa9\xbe\xb4~\x0f\xde\x0e\xf9\xc7G4\xadEM\xc6\x99\x16\x10\xc0\x07\x0e\x1e)\xca*?\xe8\xe6v\xda1\xa1\x0e\'\x98\xe7w\x11O\xbfC\xbbOa\x81%n\xa3yZ+\xf2\xa3\x0e/\xbcq\x80f\xf2\x9c\xe0_\xf3|\x18t\x1f\x86\x85D\x81@\xa8\xe3\xb3+\xbc\xf0\xd5\x9bG^\\\x80`;\xe0\xf5<h\x84\xfe\xfbO\xbcp\xe9 l\xa0q\xc2\x87j{\xb0\xf28tk3\xb7\'8}\xc4+\'\x8a\xb9Q\xf8\xe3\x06F\xb3\t\x91\xd6\xe6\xce\xd3\x0e&\xd7\xac`\x07\r\xde;\x87;g\xe0EC\xd7\xae;\xbb\xc7\xa7\x17\x1b+\xa3y\xdb\x18\x9d\x1b\xffL{\xd1n\xdf\xe9,\x0bR\xb6\x0bl\xbb\t\xc9\xb4n\xaf\x15\xf0Y\x9f\xc6\x0bi\xd3\xef\x85=\xc6\xa0\x9d\xa7\xb3\xa9#\x91\xce\x9eY\xa0\x8d\xf5\x9fh=\xe26\xd5\xc5\xf3:O\xbc\xa2\xfd\x90\xc0\xb0x\xe8\x1e\xd5S4\xea\xc0\x92k\xb4rl\xa8?\x0e\x7ft\x14\xc1)N\xe3\xa1\xea\xbby$H\x8f\x9a\xe0%CF\x8evt\xf6\x00\xbdY\xe1\xa3\x8a\x04\xd2\xdc\xa4\x83l(\x90q\xeev\xc8M\xbeb\xc4\r\x99wi\xd8\x9e\x86a\xebQ\x88\xcf^n\x7f\xc35\xf9|r\x17I\xc4$\xed\x1a\x87?5\xa7:j\x96\xbf\xbf\x05m\xd8\xe2\xcaC\xb1\x05\xb4SVN\'YZ_`\xb1\xa3\xc0\x07\xb8L\x93\x85<n\xf43\xfa^\xa30\xfdB\'\xc1\xd4\x93\x0b\x03,S\xf5\x1d\xae~\x88\x08_\xc6\xeb\xe7r c!\xb4\x17\xf0y\xab\xe7\xc3\x87o\x7f\x01\x0b\xa6\x11g\x1a\x0c\xc3<\x14\x88\x8a7\x1c\xe9\xd0=\xac\xe0\x07\x1f~)\xd2\xa1\xad\x97\xdcYDG\xef\xde }l@\xd4\xae@\x9b\xb6\xf1ZU\n\xef\xdeR\xd2\xa8\xff\x15\xaf[o3\xb8#"\x956^\xd1\x88Y\xee3\x19\xba<\xad\xb4W\x88@\\\xcb\x87\xf7NW\xfdB\x1e\xdcF\xdbap\x98%cZ7\x96\x0b\x10A\x13:\n\xddh\xc5\xf4\x9b\x9f\xbe\xafy!\x06v\xb2D^\x15\xe1B\x0b\xb4NG\x19\xb6Y\xc1\xb0\x87:\xcfJRf\xa3~\xb0\xfb\x9e/\xbc\xaf\x89\xd6S\xf0\xfb \xaf\x99\x06" \xf7\xf9\xe4\x1e\xad\xf8\x00g\x9a\x82\x7f\xd2\xd6w$\r\xc3\xb4\xf2A|S\xfc\x8cw\x1fq\xfb\xcd\xe28>,A64L\xe3\x89\x92hk\xd1+\x00\xbc\xa8\\\xc2\xa3\x10\x95\xc3\x95\xbcqO\xb7\xaa\xdc\x14\x03~\x0c\x8f=.\xa4\x99\x1b\xe8\xe5R\x05\xd5\xb8\x8awW\xd1z\t\xef\x97#o\x18\xb4\xe1\x998$\xac\xdbQ\xf7\x84 5\xe5iw\x9eK\x96\xc7\xc2\x82\xc7:\x90\x8b]\xf1\xf97hC\x8e\x14s\x8b\xd6\x90V?\xa4UG?\xc4W\x8fg\x11\xb5\x97\xc8\x03i\xdf\x9b\'\xdd\xd2\x83\x12\xf9\xd8\x9d\xea\x02.\xc6\x8b\xa7\xb8\xf1t1\xd0`!\xda\xcb\xd7\x05\x88\xd5\x82\xb0\x19\xa3\xf1O\xa2\x03zW\xc2#!\xf644\xeeng\xef\x8b(?\xa4\xb1\x129\x12\xba\x9dX\x9aI\xe1\x89J\xe8\xc7)\xf4\\\xed\xc8Sv\x17\x8clX\xe5E\xfbW\xb2\xf8\xf4\x1f\xa2/)\rJ\xef\x97L\x91\x1cR-\x94^\x8aL\x91\x9a\xf6\x17\xd5\xa5\xc9\x14\xe9\x7f\xa7\xba\xd5\x7f#\xd5\xfd\x990\x01*\xf7\xeb\x06S_\xb1\xc9\x85\\{j11\xb9M\r\xdf_\xbf\xf6\xb4\xa7~#x\xfc\xac\xb9\x01\xb7\xdaRM\xc8\xed\x87\xef\x9c\xdd\xae\xb9\x01\x0c\x9b\xb3>\xd3~\xb6\x16\r$!G\xfaLm2^\xbfp\xed\x07L1\xee@\x0by\x006\xa4\xb6z/h\xf7^\x02M\x05]|\xf3\x99\x1bo\x01wfi\x8aN=\xbf\xd0QYE9\x92\xe2\x03\xa0\x8a\n\xbf89\x01\xc34\x15\xa4\xd2\xbb`\x82\xb0\xda\xfe\xa9\xf5!_Is\x11\xd4\x03\xf4<r\xe3N\xf9\x95\x028V\xab\x92\'\x80\x8d\xfd\xaf\xa8\xfa\x12\xf7\xff\xe4\x89\xaak\xc00\x00\xcapv\x01\xc8\xe6\x80\x1a\xa9\x86\xda\xf2"\xa0\xec\x9b\x81l\x1bZ4\xf9=\xa1\x94{o\x80r\x96\xbf]\t\xfd\x14\xcdG?\x91\x05l\x92\x1a0W\xe3\x04\xd4\xab\xe3\xe5B\xda\xc5\xd8\x1e\x18\xa0y\xfd\xce\xdc\xf8\x081Y[i\t\x9f\xd9\xb6\xaaB\x80\xad\xd3a\x0eO:{\xc0\x03\xeb\xc1y\xeb\xe0\xeeY\xaa{\xc8#\x86<\xec\x04\xd7^HA4\x9c\xa6"\x0b\x9f\xa2\xe1[\xbc\x9d\xe2\xcb\x02B\xbb\x9c\x10\xcf\xbdA\xe8\x97\x9a~g\x1a\xbc7\xa1m\x88\x80\xc3\xf4k<j\x8f\x8c\xa9\x89\x96l\x7f!{P\xc3}_\xc7\x1b\xd1\x98/ @#\xf7su\xbd\x8e\xb8\xe5\x89P\xda\x8e\xe5\xae\x9f\x11\x17\x11\xdaM\x1f@\xa7K\xdc\xa1\x0b\x01\xd0B\xfd\xbc\x15\x87\xc8\xef04\x88\xe3\x96\xd4\x88h`\xd3D\x19\xd5\xff\n\xb5\xff\x86k\x0f\xb2\x12\xac\xd1:\xa4\x96\xab\t|l\x80\x94~\xd7\x15\x012x\xc3R\x81\x17t\x82\xf5\xebi\xca\xdf\x82\xeb>j\xe1\xb7\x05\xa4\xd9\r0\xf8\x19u\xc4\x86{\tM\xd0\xce\xd5\x9f\xaf\xf1\xefB\xde\xa0=\xb93oY\xf0Qjy\xb0+\xabR\xf5\x91{\x1e\xf8\x19\x824?\xbdFF\xd8\x89\x80\xef)\x07\x82\r8:\xc7 a\x1d\xc7P\x9e\xd1\xe63\x80\xec\x06@a\xad\x04\x7fu]B\x0f\xcf\xb8\xce\xd9\xe56\x9a\xddB\xe3\x11\xb8m\x05\t\xe9t\x8e\xb9\xb9\x11m\xbe\xa2\xc9HnM\xe4M\xff\xf7a\xb9\xf8a\xe4NKEa\xac\xbe\xc6{\xfet\xe2\xf4\xcb\xe59\x08c\x14\x88\xd9O\xbf\xaf\'eW\xa4\xb1H\xf2\x17\xa0\xbc\xc050\xc1\xcf\xdc \x1d\x9a\x88\xfa\xf0\xd4\xe7\xbe\x98\x8b\x987\x84\x02\x1a\x8b\xe7\x16\xb8\x1c\x0cpD[Q\x0c\x0b\xdfz\xa5\xc5\'\xb1?\xa4\x1c\xf9\x90k\x93K\rh\xdb\x9d\x07\xec0\xb2\xcb\x18\xbf\x16\xde\xfe\xf4\x03Cv\xaaGk. g\x17\x0f1\xd9F\xe3\xa90\xf2|\tFo\xdf\x86{\xa8\xa5\x88\xd7\xe9\xd8\x05\x9d>\xf3\xb5w\xff\x9a\x8c\xbf\x86\xc1\xfe\x8d\xf7\xec\x8a,\x1d\x1e\xe5\x95~\xb9\x083\xaa\xf1\x98\x86p0v\xe3g\xafW\\\xfdE\xf8\xdd\xa0yh\x04\xd7\xbf\xa6MG:(2\xf0\xbd\ry1\xcc\xbb\xc9\xbc\xf6\x9a\xf6=\x8a>Y]\x12\x96\xe6\xfe\xeb\xa4\xfa\xfe:\xff\x05\x9d\xde\xa5Cn\xb7@c\x8f\xa3\x9dA\x00\x87\xb4\x97\x0e\xa7\x1f\xbcb\xab\xf3\xd8\x18\x90=\x80V\xd5\xf3\xe9w\x1b\x83\x14\x9e\xb4\xa1\xb3\xd0\xb7\x15\xfa<\x19\xfe\x8aj\xb8\xf6\x11\t\x9c\x1bpF/\xd7x\xad\x14\xb0}\xea\x08&i\xc5\x87G\xb7y\x89\xb7\xa2\xe1\xbd\xcb\xf94g@\x8d\x91\xd4\x15\x0c\x1e\xec\xa5#\x19k\x9e\xf0|\x1c\x1dX\xd3\x90\xd3\'\xeaw\xe5\xcdR\xc8\x80u^z\x85\xf4u!\x17\xd2g\x9d\'\xedx\xe8\xa1\xa5\x8cZo \xd7\x1f`\x8d\xb750qQ\xc9sN4\xa4\x83!:\xa0S\x8bG\xd4\xf80\x81\xaa\xcb1\xf0\xf5W"\xe1\x07\r\x90 "\xd4\xc6\xed\x8c\xb9\xc7\xe2\x91\xbf\x81\xff\x05n1\xa1\xbd\x9b\xbcUh\xce\x0b\xe9\xcet\xf4\xb3J\xf7\xce\xa5L\x8fJ\xdaJ\xc2\x03\x0f?rW\xd0w-\x0c\xed\xa2\'\xee\xed~\xf3\xe9v%T\xee\xcauh\xe4\xea\xbb\xbe\x88\x81\x1d\x9e74\x92]\xd1\xa6]\xbfXc\xee\xf5t\x80\x84\xdc/\x8a\x8b\xa2i\xbd\xcbVI\xafnSo\x00^<}\xfdi6\x0b1\xdb\x0e]\xb9Q\xeec\x08\xb5\xda\xcc\r\xac\t\x05>\xf5\x96\xfe@\x08\xef\x01\xb2\x0bx-H;\x1e 4\x7fU\xc8\xa52\x98\xb6\x87\x8e+y\xf2\x13\x84P3o\x9b\xe4\xf1|n\xde\x8b\xaa0^~\x19N\x8b\xb6\xf6\xb4`\x9d\xca\xc7\xfeP\xf9\x80\n\xe8\x94UZ\x0e\xc7\x90QS\x08u\xbbR+\xd7k\x87\xd0\xe2\xfd\x98\xd7\x18\xb7c^\xd5\x87\xd0[E\xf3\x97x\xa4J\xe7\x1buE@m\xf4\xd0D\xe8E\x80\xd3H\x91\rT\xc5jq\xea;\x88\xc3\x06\xb8j#-=\xc3;G@8seZ4\xf2\x8dN\xbd\x00 \x83h7\x9c\x8f\xc6\x15\xd64^N\rV~\xbe\xb7\xe2y#\xa4\x12\xe6\x19\xe7i\xc7\x8f\x18\xad\xbb\xbc\x87\xf7l\x02\x95V\x11z\x1b\x0fR/]wz\x94\x16B\x83e\xb7u\xf0\x92-;\xeaq\xfdj\x9aOKv\xdc[\xa1\xcc\xa6\xed\x00\xb4N\x03c;\x16C\xb5\x9arg\xac\xbf\xc5\xa7\x8f\xaeoa\x83\xc5@4\xe4\xf43\xad\xdd4\xa4\x03\x9a\xcb\xe6\x0e\x03\xd1\t9w\xde\xe41\xd3\x04\x1a\xe4\xc6`W\x1bp\xb4Z\x9f\x0f^q\xff%\x8f<\xe0\xf1\xf2?\xd8-C\xb0[\xa6L\x91u>\x8f!\x97)\xb2\xff\xb0[\x8eL\x91\xfbwv\xfb\xef\xffFvs\xfe\xcfD\xee\xfa\xe5pV\xf3o\x1d:}\xcd\xab/?"\xe8\x86\xe1\xe4\xf5\xf9\xd4n\xe7\x08\x852\xf1\x82\xbb\x7f^\x00~\xb6\xdd\xe0n\x9d\xcb\xba\x90\x1d\x13^\xb4\xe7\x12\t\xb0\x1a\xe7\xfer\xbcn\x82\x17\\\xfc\x85L\xf2%158)\xe6\x8fz\xee\xd2|9m) \xf3\x9a3\x82\xf8\xb7!-\n\x98\xb9#\xb21\x1fH\xb3\xb6\xa2h8\xe8HQ\x01h\xa0\x89\xban\xd1\xc45\x91\x8d%]M\xf3*\xf7\xfe\xf2\xe5\x15\xf2\x1113\xbe\xf7\x9d\x8f\r\x03\xacD\x0e\x86\x17\xf5\x8a\xa0\x0f\xa9B\x9e\xb3\x02)1\xc9\xebwh\xece<\x04\xf1\x02\x8f8\x04\xa4\xf1\x89\xf2.m\xb8A\xbb\x0f[:"\xf0&Sx\xa7\x04z\xa5\x8d\xc7\xcbhS\xeb\xa3\x94S6\xe1\x19\xbb\x08T\xe1%\x0b\xb1\x1e\xd6`I\xf5{\x0bn\xe3\x93\x00\x17\xb8\x19\xb2\xcax\x04\xc8o\xea(\x8c\x84\x00\x9b\x87\x94B?\xfal\x81\x14\xada%|\xaa\x1d \x9e\x92\x8e\x06\xed\xc5\xc2\x85F~Qw<\xaei\xc1\xad\x87\xb1\xf7\xd0\x95\x1a7`\'\x1a\xfb\xd4\x03\xeam\xee\x0e\xa4\xd6\xae\x893z\r<\xe8\x88\xe4\xb5X\xc5\x8d\x10\x1eSF\xfe\x80\xa1\x90\xc6EP})\x9f\xa4\x14\xa0\x0f\x93%\xafy\xe5\xae%\x1d\x8b\xbb\xdd\x15iI\xcf~\t\xeaH~\xca\'\xa1\xdc\x96\xe3Y\xae4KD\x17\x11\\M\xb11\x18\xb1#\xea\xd3\x81c6\x00\x15\xd7\xc3\xa9\xb7\xcc=\xc9\xc2\x0eD-\xcdwF\xd1^%\x12\xb7._V\x87A\x80nB-4(Cx\x15\xc9\x0f\x12\xf6\x19\x80\xa0\xc6&\x0b-8\x04\xd0\xa9>\xd1\x96\xbb\x89G\x11\xee\x9b\xe6\x99<<w\x02\xf2sW,Y\xd4<\x84CO\xdd\xb3\x82}\xd5~\xdc\xca;\xc9_\xd1\xd0\xdfw\x8c\x91\xfe\x89\xfc\xfd\n\xb5Eq\xad+\xf4\xfc:\x8d~\x04\xf0\xf7R\x8b\x92\x86D\xce(\xe4\xc0\x9aR\x1fA\xd3L\xd5\xdf\xedY\x13\x10\x08fp\xc8D\x060\x8c|uM\x81\xae\xf8\xdd\x89}\x00Y\xb8\tX\xacK\x86\xd5Z\xf2\x81\x03[\x1f2I}\xed\x8743{\x02\xc9\xb8\x15@{9\xdc\xe2r\x9f\x97\x13\xc1\xc2\xd5`\xcd\x1a\xee\xe5\xf9[\xa1p\x17^\xfb\x0cu\xbc\x92WN\xad\xe5\xd4\x1e\xf5\xad\x12\xfc7\xe1[d\x18\x88\x04\xb8\x9aj|\xf4\xc2x\xe2Mp\x9es9Ct\xac\xd1l:\xcd\x99\xbb\x83\xf9zx\x9f4\x164b\x1c\xef\t\x02\x0f\x8e\x00\x16\xcd`\\g>V\xc4\xe5\xf0f\xfa\xbb\'~0tG\xb6\xd7\xfd\xf8\x87\xafx \x08\\\xbb\x81F\xeey\x95\xd0\x9e\x15\r\xa5\xf2\x82{\x15\xef\x98\x96\xd2\x91\x95\xbf\x13\xa2\xa0\x86\xd7\x1d\xfd\xaa\xc4dB\x1bO\xd9gG\xd2\x90G\xa4\xa5!Fj\x03\xee?\x04U\xdd\xc8\xeb\xd6\xe8\x0b\xcc\xfe\xe66\xfd.F\xc6\xbbG\x1d\xd1\x90\r\xf0\x1c$\x13K\xca"\xee\xcf2\xb3\x12O\xf8M\xd3\xc8\xd7U0\xf9j>R\xf2\xce8|\x7fZ\x08\ru\xc2\xad\x01\xefD\x80\xc1C\xa9\xee\xb3H.x\x1d\xfa\xe2n\x14\xcf\xbbDC\x9a\r\xd0Z&\xabt3a\xb6\rm[>\xf1uD6\x06\\\xb7\xe7\xc9\'U\x95\xb1\xb4jj$n\xf6\xd36\xba\x19\r\xf8\xdc\xa0Q\xd30x\xc02^:\x90\x8f\xd1m+\x90\xe6\xe5\xe3\r!\x7f\xc6\x1c\xa2\xaa2\x11\xfd\x93r\xde/\xb8\t\x9f\xd4\xa4\xdc\xfd"\xee6\x83\x03 \x1b\x87E\xa6@K\x9d\xd6)a\xbe\x0e\xbf\xb8\xdf\xb7\xf4F\x0e\xcf\xbc\xd5\x8a@\xfe\x0b\xff\x99w$M\x06\x12\xfa$^\xbd\x01\xdf\x80\x84k\xfa\x80\xce\xd9\xdd\x89\x85{\xa9\xcc\xa8\xaf\x1c\x9c\xb3\x98\x0b\x959\x86\xab;\xed\xb9\x1e\xfed\xf9\xb5\x92\xd6\xac\x80=P\x17\xbc\x9f\xc8M\xbe\xb7\xfc\xc4\x02 z^\x9fn\xec\xcd\xbf\xe3H\x13\x82\xe8\x1d\xe0\x91gtV\x0ce5OSyy\x9e\xa2]\x83\xd0\x90\xdb\xdeE\xd4\r\xc4?,\xe6\x9a\x8a\xc8\xaftl\x04:\xe9\x81\xa6h\x0b\x7f\x01\xbf\xd9\xc2\x10\xa3\x93\x85bN\x9c4w\xf5]\xb2=\xbe|\x14\xcb~p\xb4&`9\x08\xd4\x05\x9e\xac*I\x8f\x05\x02\xce\xc1\x8aM\\\x9f\x19\xc3C\x19N\xd4W\xcak\x95\xd1\xde| \xb3}"\xd2\xb2J\x0f\x93\x1f@\xa0\xa3lR\xf9\x90&\x86\xe7 \xfb\xe7\xc4\xdc\xfbX\x15\xef\xc5Pu\x10\x86o\x05=;\x16\x13\t\xe3\xbcm\x1b\x07\xef\x9a\x85\x1b,\xc4\xd0F\x06\x8d{\x97>\xf9e\xc7u\xa5\xe7\xf3\xf2\xb4\xa8\x07\xdal\xfe\x89\x01A\x00,\xc4\xe4\xf3\xbc\x91\xc8\xe6\xbc\xf1U\x9d{@)\x04\xf72M\xc4\x03\x82\xf6y\xe7\x89\x94c\xce\xf3\xa2`\xec6\xde\xcb%\xd5W\x1a\xa5\x9d_\xbc\x97q>\x99\xff\x02P\xbb\x81\xd8\xe8P\xa4\'\x7f\x83\xccm\xe3>Wh\xb9!\x9a\xbf\rL\x1d\xa6\xdf\xf9\xb4_(\xe9\xf5\x15\xda\xbf\xe5\x9f\x12~\xe3\'\xf4\xd8\x14\xed\xbc\xe4.\x03}\x06\xcd/W<\x12o\x890{\x9au\xed\x9a\xbd\xb7<\xd2\x07QvzUz\xf3\xb1\xfd\x8b\xf8;\x15n<\xa3\x8f@\xdeG\x06\xb8~W\xfa|\x975.\xb4\xe2L\xaa\xa8\x02\xab\xc0\xaf\xce\xc1:\x17B\xfd\xb8\xcd\xa5\x12@;\xc9\xb5\xff\xe0A\x85\xe0\xc1<\x99"?\xa4G\xf0`\x81LQ\xf8\x87\x07\x8bd\x8a\xe2\xbf\xf3\xe0\xff\xf9o\xe4A\xc7\x7f\xe1A-\x0c8\x88\xf0\x12\x9d\xbcF\x04\xd4g\x17\xd1\x9e\xae\xd5\x8f\xb0_\xde\x08\xe2\x1d\x8c\x80\xfa\'Us\xf3\x0fXt\xe5\xfa\xe5\x12Zx\x851\x1ds&u)\xb4\xed\xb4!\xb7\xc5\xc6U\x9d\x93\x1cr\x12\xb0\x9cg\xdc\xf7\x02(\x1c\xb1\x02\xa5\xf6\xc2H\x8e\xc4x\xf2\xa9V\x82\x08"\xcbG4\x15\xc2\x1d\xc8\xf3\x1bx\x1b\x1fl?\x03\x88,\x84\xd2\xf2\x1d\xae\xf7\xa1&\xb1P\xab\xa2\xb6x\xe0\xe4t%\x00\xf37\x12\xacMkj\x0f\xd4w\xcf\xc6W\xe3\xd4u\xbe\xc0i$\xc8\xae\x13`\xa8\x82\xca\xe9\xa2#3^EC\x0f\x0bi?0\xe9&\xb0X4e\x01p\xe6J\xa3V\x0f\x10\xb3\xbb\x08h\x08\xb4x\x03^\xd3\xa1A\x87@H\xf6}\xa5\x83\x05\x92\xfd\xb9\x88\xfc*\t\x01\xd5\x08\x94\xb6t\x16\xd4\xbe\xe0\xf5YZ\xa6;\x00\x96C4\x07\xf0\xe9{pjw(\xd7\x84\xc3\xdf\xb7\xd3y\xe5N\xe9\x17\xf8\x1bt\x94\x93\x03\xef;\xa2\x15k\xcf\x816\xd4\xa7\xcdg\tt\x02\xf7\xec\x11\x0f\x88\x14\xab\xad!\xa4\x89}\xadpFBzD+\xb6\xdcZAGJk\x96V\xc6\xb9\x8b\x1bi:\x04n\xde\x89\x9b\xd4\xae\xd4\x07\xfah\x03D\x0e\xd3j\x11Z]+uVc\x8a/\xc5\x8c\x8eZ\x04\x81e\x86\x92G\xa3\xb9\xf7\x07\xf8l\xff\xb9y\xb84G\xb3\x06\xd6\xbbSL\x8b\x00\xce\x82\x0c\xd7\nY\x82=\x12\xda\xe9\xab\xa6\x82\'6\x92\xf0\xea\xfd|>.W\xe2\x97\xf5\xf20\xee\xe3!_:-K\xd3u\xc3\xf7\xc5\x89F\xd2\x14\xe8q4\x1fV\xf1\xdcG\xe8\x0b\x15\x9e\xb9\xf3\xca\x9b\xf7\x93\xc4\x9a\xac\xd2\x82\xe6?\xc3\xd6K\x80\xcd=p\xfa\x9c\xd2\x031\xa6Bdvf \xa8\xeacE\x0b\x8ao?\xa4\xce@\x17\xde\xb1\x87\xa9\xe7\xe8L\xee\x85\xb0F\x9aF\x9bw\xa8\xc9\r\t\xe4&\x8f?\xab@k\x0e\xee\xfb!\xbd^BK4\xb1\x8f\xf1\x949j\t:\xafgH\x13\xf3\xdf>\x96\x10\xe7\xaa\xe0\x1f\x15|\xfc\x01\xf7\x8b\x86i\xe8 7\xe3\x1d\x06\xfe\x00\x8e\xd8\x14dK\x9a\x17<Y\xc4Ma\xd0B\xea\x10-\xcbl\xd1\xc9.P\xcc&|`\xfdy\x84\t\x9f\xc6\x99T\xf0\x08\xc2\xba\xffE\x92\xaf\x05\xbe\x96S\x8f\'l\xdb\xc0;E\xb6\xd9\xac\xbaEC\xde\t\x00\xc4V\x8c\xb8J\xd2Dg\xbc\xf0>\x91W\xech,\x97\xb7\xfc \xb7\xc7\x12\xd0F\xd1\xacFn\xb8!*0\xf0\x8e\xc9\xab<\xff\x9e\xda\xdc\xf1\xf9v\xb8\x05\x82\xfb\x84\x8e\xf9\xf7\xaf_\xd4oP%\xff\xc0[\x8ev<\xfa\x954q\xbcT\x16\x054\x05W\x8e\xd0\x8a\xfc\xb2x|159[`\xc4\xd5e\\\xfd\x1dM\x1b\x84c\xf5\xc5$\x8byH\x00X\xb7\xf4\xf8\xe9\xcf\xdf\xa3"h\xa1@\xd4\x01\x0c:\x19@\xf1\xa9%\n\x9d=\x9f\xe9\xd7\xe8\xbd\xa5\x01R\x97 \xe2D-\x86\x1a\xee}\x84\xbb\xe7\xdd\xb5\xe9,\xe6\xaa`>\x8dv0L\xb6\x03\xd8\x9d\xaa\xf2\xa4\xa9w\xdc\x9d\x81\x00\xd9g\xd5K\xea\xf4\x87\xe6\x88\xbf\xf4\xd0\x11f\x03\xc2\x1f\xfb (O\x94UJ\xa0\xe6\x04\x12\xc3!\xae\x17\nR\x1fy\xc5\x00\r\x16\xa4B\xe6\x9fq\xfb\xaf\xef?\xb9\xf9\xae\x98\xcd\xa2\xb6\xc7r\x18\xf8\xf8\x03r\xbfV\xea\x0fqG\x8e~96\x16!\xb3\x97\x1d\xe5\xa9\x10qm\xc7\xa7f\xd0;\'/1\xba#\xe0)Q\x90\x00\xf6\xe35c8\xc2\xa6\x11\xb2\xb454\xac\x19\x9f/\xe8~G\xcf\xc6\xf2\xb3\x95\x86E\xbc]\xf8\xeba\x04D\xe1\x13\x18s\'(\x12\xb8\xda\xf6\x11\x04\xab\xa6\xdd\x9f\xf0\xad\xa1J\x03\xd6h\xe3\xae>\x18\x00Y4\xe4\xcb\x14\xe2\x03\x9c\x07\xed0aX\x0cB>1\xbd \xe7\xb10\xeaw\xe3=s|\xde\x86\x1cl\xc2\x1f\xd8\xbc\x81\xc7\x9c\x16\x94[\xe8\x08&4\x06\t\xf4\x14\xe1\xf2\xadkJ<\xfc8<\x9c&C\xb8\xf3\x05\x8f\xe7\xde\x83\xd7\x1c\xa4<\xc4(u\x00T\x9eG<\x8b(\xa7\xed\x0cW8h\xa3\xae\x85\xbf\x0e\xb7(\xef|\xe4\xfd{4q\x87\xbb~\xb1J\xae\xeb\xf8XP\xda}V+\xb9\xcb\xf3\xadH\xc7X\xed\xc2\xed\x8f\xed\x1e\xea\x88\xd2\x81\x174\x9d\x08g]\x86\xea\x84!v\xa9\xd5\x97W\no"b:\xf0\xd9\xf6e;Re\xc0\xb5\x1ah\xcf\x91W\xf5\xde\x8b\xf5\xe11d^]b-\xa3\x83\xfa\x95\x9e\xacJ\xa2Y\xe5\x15\xdc!\x8f\x0b\xe4\xa6\x18\x8c\xf3\x0c-\xf9y\xa6\xde\x01{/\x1a\xd3F\x88+\xed\xe6\x03\x1a\xeax\xcc\x91\xf6\xaf\xdb\x80\x8c\x1b\x9dl\xe2H \xd8\x81_\x91\x1f\xd7:\xf2\xc4\'Z-\x97\xea\t\xfaK\xe4\xbc}\xf1.\x12\x8e\x99O\xb6\xa4v7\xfb\x0e\xb0\x1a\t\x16\xf3\x96\xbap\xae\x06R\xddG>\x87W\x8fbhj\x8b\xa8\xcdVPZ^\x86\xe3U\x84\xe68\xdcl\xccG\x14.\t\xaf\x83\r\xeb3\x83R@\xaa\x13x\\\x93s\x0eR\x01\x00W\xe3\x13\xb4@,\xfc\x0f\xba\xd3\x1a4\x00m\\\xe1\x8d\x97p\xa0\x9aO\xd4\x96*\x82g\xed\x1b\x9d\xb9\x97p\rr\x84\x0b\xf9\xca\'\xc8\x9f/\xd0\xb6\x16\xf7\x7f\xbfo\x9fG3\xff\xe0\xc7\x12\xc1\x8f\xa52EYH\xa7\xe0\xc7r\x99\xa2\xe2\x0f?V\xca\x14U\x7f\xe7\xc7\xff\xf5_0\x0b*\xf8\xf1\n\x84\x18\xf8\xf1\n\x8d\xff\xa4\xed\xf0\x04\xe1B\x91\xdcv\xcd\rH\xd1\t\xf3L%~\xe7\xae\x0b\x08\xcf\x13j\x0e\xb4\xbc]B\x8d.\x80\xcb\xedd\xeew\xbc\n\xad\x86\xac\x84\xc6\xac\x8d\x83\xe1\xe7qZ<\x1a\x07?\x14\x99\xce\x1c\x02\xb9\x1f`\xb0\x10\x0ch\xeb/\xe4\xf6\xa7T\'\x15*\xe9"R\xf6\xf9\xa4\xd8\x8d\xdb,\x8a\x1f\xfb\xe6<\xe1\x83L q\xe7\xcf+\x8ft\xe1\xd9\xa3n\x91\xb1|\x96\x05\xa5x,\x7f\x87\xeb\xd7y/1\x07\xfe*Q\x8e\x19\xc6i\x81\xd7\xe2\x11\xd5[6:w\xabr\xbc^\x01\'\xea\xfcm\xbd~\x01\x08\xb51\xb8#\x11\xbcc\xeb\x87\xbb\xdb<\xc3\xf1\xef\xc9M\xda\x89\x045\xcd\x00\x01,\xa96\x06\xee\xb8\xc2\xc3iT\xc7*\xcf\x1c\xaaw\xbd\xcb\xa3\x16>\xbe\x08\xede\x11\xc1WB\xe5\xf7\x80Z\x03\xe0\xa8\xfd\x8b<\x16a\x87\xa0<\xe4\x8d2\xda\xba.\xd57}$)\xc5\x8c\x8b\xe3\x96r\x10\xe9"o#\xef\xe0\xe3T\xcf\xc8h\x89\xf2\xa6\x83\x9d\xf8\xc8\x8b\x87\xec\xd1\xfb\xd3\x08\xae\xbe\x05u\xb5&`\xd6\xa5\xd2@\xa4\x00k\xb4\x05%\xc9\xfd\x0eY\tH\x05\x96\x10)s\xb0\xf0\x1a\x84\xe4V\x05\x9cqX*1\x02\xfc-\xcb\x8bo\xc3\xb3\x1a\xae\xa7\xf2\x92\xdc\xba\xb0\x94\xe6\xa0\xeaF\xa5",\x04_\xb5T\x84\xd5\x03LDz\xf5\x1e\x1c\xab\x82{\xaa\xed\xa9=W\x0f\x16\x97J\xb4@\n\xf6\x89\xa9\xc54\xcb;A\xa4\xfe@\xadOh\xa8\xf4\xb17k\xdc"\xd0\x8e\xb0\x04\xbd\xfb\xb8\x7fM\x0ee0\xfc\x18\x11~JG\xa5\xbcP\x10\x93r^\x83\xe5\xc7\xd57x\xcb\xc0\xd7\x81G\xef\xd3T\x9am~\xc0[\x9fL\xb3k\x82\x89\xc6\xb8[\x9bz\xady\xce\xa0Dy9\x87\xd5\xe5\x9e\xf6\xb8{\xc0\xd5\x11_\x06\x88\x1a\xc3|\x9a0C\xe6q\xfa\xf5jzr)Hj\xd0\xcc\x91Z$\x1a\xc7(,\n\xf5\x11s\xe9\xb65-\xd8\x82-\xbeY\xfcJ\xf3\xd6\x05\x1c\x0b\x82\xe8\xfb\\\x82Q>\x00P\xb4\xe6\x00\xb6w\x92\x01\x0c\xa31\x80\xfc\x95_\x95\xbc)\xf2c\xcd\r8d\x1d7|~v#\x0e\x89\xcb&\xc0\xbf\x1a\xa3y\x1a\x04"^?\':?!\xed\xdd\xaaX\xfd\xe4Af!\xaf\x1a \xd7\r\xa4No\x8c.\xb4\x1d\xd2\xd6\x1bT[\xfa\x1e\x0e:J\xdbY\x18\xdb\x81\xb7\xf7\xcda\xee!:+\xa5\xcexs\x90\x92\xa6\x8a\xc5\x1c\xe7\x9cM\xa8\xae\x00a\x19XXS\x9a\xe4pQ\xf4}\x88\xabo\xe3\xf9]4\xf1\x0cxr\xf6\x01Q\xd3\x02\xe4X\xe3\xf5\x9b\x04t\x10\xab\xd1g\xd7A\xf0\xbd\xf0\xd9\xbeB:\xf5\xc7\xe8\xd7R\xdb\xabp \x1eb\xa4\x01L\x87\xbcZ\xc85\xd2@\xb0\xf0\x06\r\x86\x94\x81h\x05\xf8L H\xfa\x0c\x13\x84\x93\xec \xeb\x9c\xa5\x1a\x0cd\x1fk\x1c\xb9\xb3\x12\xc3<\x00\xc0\x1f\xbc(\x96a\x94\xc0\xa9nQif\x0eT\x1a\xe6\x91R\x1f4\xa1\x8d[\xcd\x01p\xfbp\xf8N\x87J\xc4\xe9\xf8m<\xc9\x98j\x00a\x0b)\xb4\xc5\xfby\x16\x10TC\xe6\xac\xba\x1c\xc8\x9b\xa5\xc6\xf0Z\xe1\x97{\x12\\\xcc)\xb5M\xa1\xc9\x86\x80\xc0\x0b\x80\xccQ\xb1\xa8\xebi\x12\x08|\x14:\x13\xc0\x1bF\xa2\xf3\xbb\x95\x91h\xfd\xc2W\x9e\xb6\xb1\r\xb7\xabz($\xdeu/\x8c\xd8\x1cZp\x84\xf19\x80\x9e]\xf5\x10i\xf3\xf4G\x1e\xb4\x8d\x10\x83\x9eC\xf3\x99\xe8\xe2\x02\x0f\x95=\xb9\x05\x95:REk\xc6\xc9\xa2\xc8\x80\x1a=\xe4\xdaN\xe8v=w\xc5\xd9\nEA\xeb\x9e\x80\x93\x9d\x1c?\x86d\xb8@3\x82\xb4\xa0b4t\x08f\xe2u;m\x19\xed\xc4\xd2z\x1ewi{\xa2\x85\xce<\xeaB\xeb\x11:\xdf\x02\xf3\x1e\xd3H\xd1\x9d2h\xe5I]P\xe9\x98!\xd2a\xdf\'\xb4I\xab&\x06\xf0\x0b\x90\xf4,o+A\xfe\xbbH\xcc\xbb\x1f\xd0QP\x14\x8d\x05\xf3\x88\x97\xd0 \xf1\x02\xd9\xd5\x85\xbck\xc8G\x99\x81\x05\x1f\x80\x84H\x1c\x11\x8dS\xae\x85\x91\x10/\x1d4\x91Ra\xa9s\x9e"\xb9!\xd6F1.\xe3Y\xc9<\x98\x8b\x94w\x8e\xc7\xdd\xcfs\xbd\xb8\n\x1b>-\x81\xbf\xee\xa3\x1d{\xb6\xe0\xa1YV\t\x9e\x83\xb4=,\xc3\x88N\x97\x05P\xcb[\x07P\xe4\x0bqG\xecw\xa4\x92m\\\xcf\x87^4+\xa7\x89{\x81\xe9/\xc4K\xe2,c\xa3i=\x9b\x8fr\x8c3y$\xe1\xfd\x1dq\xb1\rZ\xd5m\x90\x88\xb19y\x01r\x9c\xe6S+\x1a3\x90^\xbc\x07!\xb2H\'\xb9\x08\xc3.\xf8\xc0\x80\x01\x0f\xde\xb2\x046 /\x8c\x80\xf5\xa9\xe7\xbb\xcd3`\xc91\xbeov3\xd7EbH\x93Op\xe1I\x99;\xaeY !\x87\xe7\xe0^\x1a)\x93\xdc\x97&\xcfG\xa8\xff\x96\x1e\xb7E\xa7\xf2\xb8[\x96\xd1#\x08\x82\xafo\xf0\xe5\x127\x1a!\x1d_\xf9ZE\xf5>\xbca\x05VFF\xd4\x1c\x8a\xefb\xd0\xdf\xe1<A\x9exu\'x\x9c:\xf2Ea\x98P\xe8\xfa\xc6\xc5~/D\x81\xe7\x92\xd3\x8540\xe7\xd0\x97\xf8\xa7)O\xfeA\x8cJA\x8c\xd52E\xcd\xf9\x04j\xadLQ\xf7\x87\x18\xebe\x8a\x86\xbf\x13\xe3\x8d\x7fc=\xb5\xeb\xbf\x10\xe3ED\xb2Fq1\xf2*|\x1d\xc8}\x98(&\x06\x91<B"4\xd1\xae\xb9\xa3\xe29W\xff\xc20Nq\xbf\xceE\x88\xb3\xa1\x97e\xdc\xf1M\x0c\xf0\x02\xb5\xfd\xe4\x9a\x18\xe0\xd2N.B1\x13\xb7C\xe6\x8d\x02\xbe4\x01\xb9\xa0\x97\x1e\xc4\xcd\x8ch\x0b$q\xccCI\xa3k\xa8!\x12\x06m\xe5I\x9b[|\x12\x00\x99\n\xe7\xef\x00\x97n\xf1B\xc8\x93\xf3\xacO\xcca\xc5\x88\xa92\xe4`}\xf0\xd1\x9dpn+\xd5\x11I\xc47D}\xb7\x94u\xa9\xa8&P\xd4\xbd\xaa\x01`K\xb1\xbc`\xec\xc6[\xcaHj\xf5\xcc\xc0`I3\x84\xde\x08\xd1Q-\xb4m\xcc\x0f\x1e\x07\x8e\xa0\xce\x1f\xa2\\g\x95\xc6\xdc\xb4\xbf\x81\xc7\x11\xfb<\xfa"\xd5\xed\tR\x9b\xc3\x14$\xa3\\\x87D\x10\xf9\x1c\xd00\xed\x9c!j\xc0Ikr\xb8\\\x1d@g\xe4e0w\xb8G\xfa\x18\x82UT\xd4t^\x7fm\xe5X\xe9g\xf2\x0e\xa1\xbf!j,^\xfa<\xa5\x15+\xee\xb6|\'`A\x0b\xb2\xf4\x18L\xdb\x1a\xe4\xa4/*?i\xe7\x112+\x15\xe8\x7f\xcf\xc8U*HVR=ZB=\x81\xc5<l\x8cL`\x08\xef\xde\x8caM\x10\xdc\xf4\x88\x9a\xa4\xc9\xda\xafY<\xfa\xca\x82\x9b\xbc\xd0\xf65\xea\xfb\xf1\x13\xa6\x1a\xc4s\x1a\xe1s\xe73\x9d\xb0oK\x00H\xed\xf7SD\xfb\x17=\x84\xe2\xaa\x07\xff\xb6\xa0\xfaB\xf8a\xfd9\xe9\xbb!H\xbas\xf9 \x9a\xd6\n\xd23q\xc9<M(\x82\xa9W\x1b\x8f\xd8\x93\x1e\xd1n\xc53\xe5e@l\xa4+\xdc\xef\x8a\x00i\xe7\xf6\x1f0\xa2\xda\xc0\xe3\x9cu:\x1d\xa9\x1bH\xb3R\x8ePZ\xa2\xae|\x00\xf6\xfa=\x07\xea\xbc\xa1\x0f\x06\x00\xd6\xfaY\xdf%\x8d\r\xa0\xae\xaf\x80\xa7-x\xc7\x9d\xd7,\xe1DC\xd1\xb8}J$@~\xb7i \x86\xb6>G\xbd\t\x04nm\xd0\x92\x0b\x90Q\x83\xb77\x8a\xc4_\x1a\xd7\x837RsVy"\x83\x8e\xa2\t#\xbc\x0b\xcd\xff\x9d\x16\x1eC\x96I\xd5\xd7\xdc|\x0fM<\x80\'\xac\x9b\xd0\xae\x8d\x03/\x9be8\xa0\x17j#R\xb9E\xf1\xd2\xa5+\xb4\xe2`\x7f\xcb\xf8+\x10l.\x004$\xd2\x89\r\x04\xed\x8cT\x9d\xac\xb9\xc65Y\xd7\xa8\xf3*\xf5\x7fs\xe6\x16/\x08\x8d\t8\xf5n\xdceI\xb1i\x8a\xc5\xf2\r\x9a3\x84\x11?\x8d/\xe3\xf5\x1f4\xa1\x03~\xe8\xe5ee\xa0n\x9a\xd8{p=\xe9G1/~ErrF-\x99`\xd8c>3\x0f\xa9\xc8\xd3M\xe7\x13\xbf\xfb\x9f\xf0\xb2\x15\x12\x1b\x0b&\xbf=OJ\xe7m\x07[}j\xb8t\xf9\xdcm/\xd34\xf7V\xd1\x989\xcf\xdf\x13EM\xbe\\\xe7XA\x13?\x1d\x12$i\'Hq\xc7\x89\x9b\x1c\xa8\xc3\xd1\x11Y\xd72\x8f\xc3\xdb\x8e\xedy\xd9]\x9a\xfdt\xa7\x9a\xab\xd4\xe4\xae\x9bJ\xfd/\xddy\xa0\nC{R\x04[\xee\xd2\x98 CC\xaa\xf6x\x87G4\xe0\xda\xa6\xf8\x9c\x02\x91\xe2\xc7"\xe3\x9a\x149\xbf=\xd7\\\x11\x9c[\x88\xd0\x12:\xae\x15b\x17\xdcx\x0f\xfd\x9e\xcb\xc9\x03\xea\xeeQ\xbf\x87$\xe0X\xadC\x93)\xa5/x\x05\x81\x8a\xc4\x12=U\xf1\xde\xc5o\xbc\xe6/j\xcb\x9fy\xa4\xa2\xcbG\xdf\xee~\x0c\xe4C\xe5/\xe8\xca3:~\x0f\xab\xedKEo\xfd\x88\x97\x8e\x9f\xb4\xee\x9b\x18\x0ed\xd9\xe6\xbe\xc0\xef@\xa3i\xbfg"\xc9\x9c\xa1\xda\x94\xdbx\xe2&of\x8aI\xc1\xb3$\x00\xa9\x99\xe0\xc2\xa7\x82\x0bi\xce=\x05O[\xd67D\xc0\x9cV\x00\x8e\xbb\xac\xf9\xc0\x8c\xaa\xef\xdd\xf9H\xed\xb4\x7f\x1fo\xa9\x01q\xd5^\xaf\xa4y[:{\xf5\x18\xfe\xb3\xf6\x9c\x87s\xf2\x85d@\x0b\x86R\xdfd\xf3@f\xf6G\x04\xd0\x8e\x919\xdc\xaa\xdf\xea\xcd\xc3\xc0\xa8\x18>(\xe0\xa1\xebvy\xc1\xdf\xa1\xdcZ/\xbf\xf5\xe5uH\x87F\x9a\xf5x#7\xa3ZW\xb4|\x9f\xc6\x8b\x8a\xb9\xb7\x84\x86\xe5\x16\xa0DQ\xc6S}\x91\x06i-H\xd4\xc5C\xb5}\x87\xbej\x04`\x1d\xd2\xe8SAc\x15\xeex\xc8i\x1e/)\xf9\xcc(\x0cA\x04\xc5\xcd\x0b\xc8AC\x80}K%\xf8r\x82\'\x1dx\xcc\x02#\x00\x1a\xfd@\xb5")@\xc4\xcf\xf3b\x01\xb7\xe5@f\x9d!\x944\xb4\xe4EM%\xf2\xfcP\x80\xc482z\x98i\xb6\x12\xf0\xba\xcf\xe3U\x81\xbf\xb8\xf1"\xd5\xe8\x82\x92\x9b\xb8\xe3\x13\x02\x17pM+/m\x1c\xeee\xca\xa9\xf5>"|\xa0\x10\xf2r\xb6\xe81@ZH\xcb\x03d\x86m\xb6\xe0\xad\x94H\x165\xde+\x99h\x08\xe4\xc5\x022\xd8\x16\xea\xb5\x01\xd3\xc1\x1fZ\x1e\xe2y`\x0b}\xc1\xf5\xb0\xfc|6wEH\x9c}\r\xad\x10\x95\xe1\x03\xf8o)\x9e\xba\xee\xf0\xe6}n\xb7\x16\xb7\rQ#4\x98i\xee3\xa8!\x95\x10\xd6\xf0\xd1\xc5 :uK\x7f\x8f\xd7\xfe\xfe\x86`\xeb\xcc\xa6\x9dr\x9a\xca U\x80T4\xd4E\xf3wX\x1d\x7f\rP=\x99\x87\xf6\x0cy\x03;\x1b\x90\x86>\xf3\x03\x96\xab\xb9\xe6\x05\xa2r*\x1fFXM\xe1\xf6\x97\x17\x9e\xc3;\x06\x90\xf0\xb7\x82\xcd\x07\xe9\xf0\x1f\x0c\xda(\x18\xb4I\xa6h\x0e\xe9\x13\x0c\xda"S\xb4\xfea\xd06\x99\xa2\xfd\xef\x0c\xfa\xdf\xfe\x8d\xa9\xa5\xf5\xbf0\xa8\xb6\x1dk\x92t>}\xfe^\x8e\x84\x92\xe6Bd\xdc\xf4\n13{\xafD\xac\x91P\xfbEG`B\xc7;K\x13\xde\xbc\x8a|j\x93&\xcdbJ\x1ep}y\xe6\r>xy\xbeQ\xe7e\t\x82q\xcdST\xdfq\x97H\xc7\x8f\x82\xe2yBV\xc1Kf\x90\xac\xb3\x90\xf57}\xe5\x92\x14\xd9\x0f\x86\x07\x8c;Y\xe1\xfae<]\xcd\xe3\xd11"1\xf4\x83\xaa\xe9\x01\x81\x81\xf1\x80Ru"?%\x81\xe6\x0b<\xff"\xe3\xd3\x1d);\xc4h\xd4\xc4\xc4\xf0\xe1\x1bnQ\x06\xe8\xe4\xf1\xba^\xd8\x8b//\x01DRn\xc8\x9a\xa7\x82\x13o\xd3H\xc6]\x9a\xc4\xdb\xdc\xb8\xcb\x81f\xed\xdfs\xdbe)5\x84\xbaD\x06\xf2\r1\xb7M#\n\x00F\x1f\xb5\x03\xc6\xc0F\x0b\xf0\x98\xde\xaf,\x913\xb0\xb3\x9a\xa6C\x805\xd5\xb4i\x16\x0f\xd5\x8dd\x99\xfb\x93x\xfdV\xb1\xe9O1\x8bE]\xb1@\xc86Siz\xbf\x93\x97\x8a\xefQGP\xac\'\x9d\x14\'H\x9bW\xea\x04+\x9ef\xf3\xca\x15ODa\x17\xd7\xdc\xe3\x89\x181\xc3qF"IR^D\xd3\xc0>G\xc5@\xda\x8dgY\x002U"bj3\x9c\x97\x9e\x89\t\xd1oR}f\x8bS\x959\xb2\x93\rj\x0f\x0f\x06\x8f\xf5R\xf57\xeeM\xa5-\xbc\xc2\x89\xea\x9e\x80\x16\xce\n`-Q:zR\t\x11\xa0\xe6\xb1\xa7\x08\x91\xe3\x18j\x8c57E_f\xd1c\x95#$\xcaV\x16\xfd\xc6\xf3\xbb\x81l\xb5b\x0537]l\xbbpD7\x0fC~\xc6\xc1p\xfd\xba\x96\x10\x18+\x80\x07\xb5\x876\x12\xc2]\xb9\xe9]\xb8Q\xcf;Xc\x94\xdb\xbcy\xecUh(\xc2a\xca\xc1\x18=\x06\xe3C\x1f\xa2i\xcb\xb4\xe7\x05*S\x9b\x94\xe5\x7f|\xcd\xa7Exv\x7fN\t~\xd1\xa6\x06w%\xe0w\x87\xeb\xe3}\xa0.\x06\xc5Z\x13|\xb2\xa1\xd4\x9e\x1b\xcd\x1e\xc1\xca`A5\x1f\x19\'B\x8b\xae\xa2\x03\x13w \x1f\xeaR\x91\xab\x8d\xf0\x94!~\x9c|\xc8\xa2\xa5[\x18\x95v$\xdf*\xe1\xcc\x99\xae\x18%$d\xdf\x94|j\xf4\x99\x9a\x7f\xc6\xc5\n{>N\x05\xb7\x1dSS\xb1\x1e\x9f%\xea\xd1\x81\x11,w\xe0\x93kz=\x86f-`<\xe1n\x91rK\xf7\xf7\xbcmL\xad\xd9\xefo\xd3o9oD\x18\x01}\xa9K,9uE\xf2\xa2\x93\xb1\r\r\x7f\xb2x\r0k\xe0\xc6|\xda\xc9D\x83\x11\xf0\xc5\x18\xbe\xbeD\x80\xc5\xb1\x014B\x0b\xaf8S\xfd\'\x17\xe0\xe7$m>@s\xc6\xd0\xfc\x15\xf8j\x17\xfc\xf4\x98\xd5v\x0fC\x1c\xa5|n0J\xccy\xb7{\xbd\x11\x98\x1a\x89\xaf\xda\xddb\x8c\xe1m\xc8\xfc\xdf\xf8#\x13\x18\x16\x99\xe5\x15\xb8\x00\xb8;\xd608#\x96\x86\x8ch\xe0\x92\x85\x16o\xdd)\x84E\x17\xb9]\xce\xeb\xc5q`\xf6\x05n\x8a\xe5\xa3\xe0\x1f\x90\xf5\x97\x00\x9e\xbd\xfab\x010\xa7T\x0c\xc6O$2\x83<\xa6\x05)R\xe7\x0f$;\x80\xeb\x04\xf1\xba\r\xa9\x7fap\xba\x1eAi\x8d\x9c/,h^r}J8\xa8g\x80\xba\\m\xe5\x11\xb7h\x90\x9b!h\\_*}A\xa6G\x04\xa7\x1d\xe3&\x84L\x12\x8d|\x17h\xaf\xc3\xeb\xcfy\xcf\x99O\x95o\xa4\x1c\x139\xea{\x915\xa0\xa3;!\xb1\xb1\x08\xc5\xd5\xf2R\x9dK\xd2\xbcD\xd7-\xda\xfc\xe8\x12\xe8\x97PQ\x9a[\x95\x05\xe2\xda\xc3\xeb\x07\x1e\x04\xd2\xe4\xc3\xf7\x18\x05h(5|\x0b\xd4\x19\x9a!j0\xeb\xa8\xbd\x04\xc3\\]E\'\xa1\x1f\xae\xdf\xa8\xc0\xf7\xaa\'F4\xfd+\x19\x81\xd6\x93\xc3{\xf7\x93\xd2D\xdd\xa65\xad\xca#~e#lzx\xf2\x8a \xcaH\x0f\xa0t\x7f(\xe2\xb2\x91g\xbd\xc5j\xec\xcdHD\xfc\x89T\'\x0c\xe2\xd9\xf8\x88./:!ck\xa3\xcd\xab%\xc1\x1fx\xec\x92$&\xc6\xf9@\xdf\x94\x06|R\x81@{<%\xd3\x01\xd2l\x89E\x1cZ\x8atC\xb7\x90\xba\xd3q~\xd9+Q\xd3\xca\x0b7@\x80\xc9\x18\xa1&\x1dXl0\x06\x969\xb0\xd77\x8a\x0b\x11|\x00\n\x99\xa0\x051\tqO\xcc\xadf\xe5\xe5\xf3\xa0R\xcb\xc6\xcc\xe5\xb3\x01\xda,\xea\xbf\xd6K\xd1\x881\x9a\xca\x81\xdd;\x92\xc4\xb2\xe4J\\\x01\xe2\xb2]\xd4\x15~\xa6\x89\xf7\x10v\xc8\xe4\xf2\xa5}9\x15\xde\x88\xb0\x93\x10:x z\xa1\xcd\x9d\xd1h\x89\x94\xe3\xb9\x03\\\xc6\x15\xbcdPH5\xef\x1c\xe0}\x83\xdc\xf8\x08\xe2t\x16\x81\xac\xa1Ig\xdaH\x81 ;\x82\xb4\x84\xe2\x9b\x0b\x92\xdaV\x0b\xc7:2\xe3\x85\xef\xdc\xee\x07\x98>\xa69\x7f\x1fj-\x91\xfb!\xc4\x8f3\xee\xa5rk\x16\x8d\xe4\xdc\xf4\x04\xe0t\x95\xc81r\x13U\xbc\xaa\xcc6\xa1\xe3_1\xf7C\x1fX)\xe4W\xfd\x00=C\x8c\xe1\x13\x13\xdc^\xe1\xd4\xe5\x95\x06s\xf0Z\n\xf5\xe5r\xbd\x9b\xa0\xc1\x19^\xf0\t\x8b\x02\xec\xa3\x9d<\x7f\x9f6\x8c\xacHU\x860>|\xe7\xc7\x03r\xed\x0b\xa6\t\xdc\x17\xc4\xb3\xf1\xbe\xfa\xff`\xbf\x0e\xc1~\x9d2EWH\x9d`\xbfn\x99\xa2\xe7\x0f\xfb\xf5\xca\x14}\x7fg\xbf\xab\xff\xc6\xfc\xf1\xc5\xbf\xb0\xdf%)\xad\xdbBB\xf6\x1c\xe2\xe8\x94\xfa\x9c\\\xa8+M\x9e)\xed[\x10\xb5\xc0\xa2\xee\xa5\xed"M\xbf\xb5\x80\xde\xbd\x8d\x0f4\xdc\xf7$\r>=\x00\xc7\\\xa5\xfe\\j\x00\xe6l\x14I\xbbQ\xbd W\xfbL-\xcb \xbdk!\x14\xda\xf1\x84\x13\xda.\x05\x8a6\xc4\x9d\x17\xb8H\x15\x104_\xc5G\x8aX\xae\x11i\xea\x010\xa3\xc1\x8f\x1a^ADLK\x93hZ\xd2|\xdb \x0f\xfa\x8b\x950G\x88\xee\x05\xae\xcf\xa35\x8b\xb8\xaa?\xd3\xa0V\xa1\x10y\xe3\xb4\x93h\xc1+<.0\xa6\t\xd9\xde\xa6\x0fwiK\\\xf7MP\x9d\x03\xa0".\xe7\x01-x\x89e@n/\x04T\xf4\xd9\x9e\x17\xb9\xd0\x19\xf2"\x1f<\x7f\t^sX\x14CSby\xfe \x02\xa0=\xc4\xeb\xb7\xa5\x12\x10Q\x95\x89<\x91\xa7\xaf@l\xcd\xfb\x06\xe1\xda\x13\x84\xce\xb8+\x9c`\xf7|S\xaa\x9f\xc4v\xa2\xaa\xda,\xc8\x0c\xaa\xb7\x05\x06Z\xff\xf8\x8a\x8e\x0bHeo*\xed"L\x14\x8b\'\xafh\x16\xe1\xfd\x1bB\tQ2\xcbM\xc6\xd2\xf4\xf3\x06\x86\xaaNjoa\x14\xd7G\x11\x8c\xc7\xaa\xa7|\x8a+N\x93r_\x8a\xf58\xde\xd1\xa3\xf3]\xa7Iz\x0e\xc0\x8d\x0e\xae\xab\xa4\x8d\xf0\x8ar\xee\xf0\xbdO\x0bIx\xf5\xd6\xf9\xda\xd3;\x7f4k\xba\xc0P\x17\xf0\xd0-\xb6\x1b7Q[<\xd0\x90\x1b`@\xa8\x83\'\x050\xf4<\xact\xe6\x0e\xa6\x9a\x8d\xa7\x83r\xea-y\x82\xf1\xefu\x91J^\x8aq\xdd\xd63\x07\xa9\xf2q\xd9\xa9\xca\xc86\x93vR\x80\x99\xbf\xa9\xcdC\xf45\xec\r\xcf\xbdBc\xd4t\xe2\xe3\x8ck\x7fSc.O\xc9\x91^#\xcf\xf8\x93\x01\x06\xf0\xb4\x0f\x86x\r\xc6\xdb\xca\x02\x10\xcdr\x97\x9cw\xf2-\x01T\xab\xdcH\xe2\x1bM\xde/\x18\xe1\x98\xc5\xce\xcc\xc1\x1c\x1f9u\xc6\x82\xd9jy)\xbc\xf0>0I\xa4qHU\x87\x01<\x9d\xca\\\xa4\xb5b\xd5\x88\xb7\xbf~\x04\x8a\xce\xd2\x98U\xc9\xf9\x8b^?W\xbet\xac,\xa1\x13\x91;\xa8\xeeU!\xbd\x1e\xbd\x13 \x8a\xb4\xac>a05\xd7M}y\xb5\xd4\x89\xb7sAuKb\xbf"\x9d\xc5\x84\x19I3\x93*s\xf8\xfa\xe2\r]\x98\x7f\r\xb1>\xcc\xeby\xf0\x8aF\xbc\xa6\x96\xe7\xdd\xa4\xfd\xa9\xb0B\x03\xa8\xb5Q+\'1\x83\xf7\x15\xf6\xb8T\xac\xfb\xadE\xd3\xd6\xf57b\xd5\xf6\x1dh\n\x1c\xeaG\xdb<\x94E\xa2\xeev\xed\xe6WV\x99F\xbf\x97\xf6\x0f\xf1\xc9OdO\xdd<c!v8~\x13\x856\xdc\xf7\xf4\xbe%m}0\x12\xe3A\x1a\x03\xf8\xf2"\\f\xb8\xacJH\x195\x84\x04\xfe\x9aq\x11rFZ\r\xc4\x05\x18\xdd\x06i\xddw=#\xf6\x07\xed\xb8X\x8b\n9\x17\'\xa9\x1aF\xcc\xa8\xb3\xc6\xf2\x8bU\x1e\xcd?\xce\x02m\x8e\x8b\x8c\xa7\x10*\x066\xbf)\xd6 HT\xd6j\xf8(^\xebr\x8a/\x92\x99\t }\x83Xf\x0f\xa2u\xea\x14E19b_qY.\xb7<\xe0\xa10\x0c\xadX0\\\xa29\xdd\xcb\xf4\xdb\xfc\x9a\x01\xad\xde\xe6\xc9\xf79\xce\xd4E;~\xe50z#m\x05\xc3L\xa0`\xd8\xbc/\x82F\xcb\xa9\xb3\x9c\xfb\xa8\xd6\xae\xdc\xa22\x9eG\x12<\xef\xa7\xd1\x98\x1f\x9awM7,\x13\xd4\xb5\x9a\xaeD\xec\x82\xed\xf3\x93h\xdcA,\x04\x92X\xc5\xeaq\x83\x1b\xd4r;\xfd\xce1\xcd4GcT\xf1\xdc\xa0\xccy\x88L\xf0::\xdd\x9d\x92\xcb\xdb\xb6\xfc[\x0f)\x84X\xe8\x18K\x8dG\xd8\xcd~\xa0\xa6\xcb\xdcR$\xb6\x00#\xd3\xd9\x8e\xc0\xb8\x8d\x93*\x17P_\xc7\xfb\xcf\xc0p\x8dZi\x1fHm\x87\x81Y\x13{\xafi\xd6\xcbM\xe4\xba\xb3\xf0\xcf\x8d\xac"\xeeM\x11\x932\xd5\x8eo\xc5d<\xed\xbd\x8f\xf5L\x8aEF:\x8b\x00\xd9\x82r\x87\x16\xfa^\x82\x80\x1b1\xc6\xb0\r\xf2\x80\xb7\xc8p\x8f\xe0\xb1\xd0\xe9&\xd4\x17!\n\x1a\xcc\xfd\x03q\xa5&\x9aZ\xcc\xa1&WDq\xac\x03Z\xb3^\x92\xcd\xc7\x97D\xfau\x87\xe7\x95\xf0\x88\xd6|\xc8\xebaGShLu\x9a\x9eH6E\xfa\xa4\xbay^+\xbf\x90\xa9@\n\xf0SW|\xfe\xd6\xf2\x1b/\xfa\xf0\\\x04\xb5\xb9\xbf\xa4I\xa1;\x87J\xe4?\xc44\x90\x81\x99=|g\xbc\xe0\'\x1e\xb8\xf3\xc3\xfe\x9b\xaf#m\xd2\x9ac0\xba\xa4\xe2y\x9b{\xbc\x04\xd5\xb8\x10J\xa3\xd2\x12\x1f\r~\xf1\xa6\x05Eb\x16\xb7|E\xfe\x0f\x96^\x11\xec\xbb\xe3\xc5\xd5<\x95\xf1$\xaeXP%\x02\xb2\xf3\x86\x8e4);\xf2\x11\xe8\xddF\xbdQ\xc0\xbf\xd6\xb2\x9c/\xdc^p\x93j\xfdy\xb0\xa8\x8a\xf7\xbd\xc1\xd2\xc3\xc8\\4,*L\xee\x8a\x17t\xbct\xe1\xb9\x02\x9a\xf5|\x97M\xcd!\x8f!)\xa4tS\xa8\xbb\x07\xdc[\t\xff\x9b\xfd\x91\xa9-\xd6P\x1eI\xa5@\x134fRH\x8b\x1f\x1efqG0\x12\x9fc\x04\xc0!/g\x8br\xa8\xdd\xaf<\x9a.\n\xb9\xcb\x83\xc4\xca\x90\x9e\x93\xa3\xce\x05\x1b`\xebP\xd2\x1b\x88\x95Vj\xf8\x07s\xf6\x0b\xe6\x1c\x90)\x06C\xfa\x05s\x0e\xc9\x14\xc3\x7f\x98sD\xa6\x18\xfd;s\xfe\x8f\xff\xa2%I\x1d\xb1\xe1\xca\x99kL<\xe0\x08\xfb|v\x07\xf13\xcf5J\x1e\x8d\x11\x13\\\xb1\x8aJ \\5\xcd\xbe7\xa56_\x8f4t\xef\x08t\xb8\xa9\x90v\x07A]\xfb\xf0N\xc6\x0f\xa7\x87\x99"ej\x0b\xe4\xb1d\x1b\xae\xd1\xaf\xaap2\xcb#\x15r\x80\xaf\xf9oEB\x18oB\x07n\xae@\x87\rp\xc3\x01\xf7\xeb\x88\x19~\xb0\x97\x8ck\xac\xa8\xfe?\xc8\x906\xbe\xc2\x19\xcf"i\xa0\n\x02\x1cX\xf2\x8b\xdb"M]_\x08\x06ZQ\xa4?\xe3~QH\x04\xc2\xd9\xa3\xbd\xfcP\xed\xf7 \xed1[\x84\xc8\xf9\xc1\x0c7\xc4\xc1\x0c\xb8\xa0\x91\xce\xa2\xedy\xc5\x1b7\xad\xfb\x82+v\xf0\xc6\xea@\xb1.\x18\x03\x96q\x15\xc1^\x83X\xd9\xe3\xb6\x08\xc7H\xeay\xca5\xe9V\xe7K\x82t\x92\xc8\x03\x11x\x84\x983^\x82s\xe5\xc0$\xcb\xb4i\x13\x8c\xbfw@\xbf\xe2\x80\t7\xdc\xab\x91\xce\x0b8\xe6\x86\n\xda\xa6\xb6O\x85\xe6\x11!!\xbe Qj\xb9j\xea\xec\xc3\x0b\xf7S\x954\xe7\\\xc0\xcba4\x10\x1c\x85\x1b\x9b\x04\xbfj\xee\x05\xd34\x1de\x86\xd0j*\xe4\x1cD\xe8Q\x19\xcd\x85\x15C\xd2\x9d\xaf\x07b\xdc\xeanx\xc2\xbe]\xa0\xabv\x9e~\xc8C\xd9\x10\xab\xb5\xe2M\xa0\xcb\\)o\xadv|\x1e\x10%\xa8\'\xba\xb00\x10\x084F\xe2\xc0\x8f\x95J\x85\xd8\x10\x8a,\x1a\xa4\xa0\x91\xa1u\xbfc\x80Q\x9d&0x\xaf\rO\'\x02\xf6\xbb\x10:R\r\x88\xb6Xc\x86\x11O\x11|\x134\x1f\x08\xd5\xbb\xccsb\xe6\x8a\'\x7f\x88\x9a\xf3\x18\xf3\xefe\x9e\x0fE\x88\x06P\xf3\x97\xe7\xe5\tpgUd\xa0!o\x89\xd9\xc7\r\xaa\x86\x12>z\xc1{N\xbc\xe3\x92Cb7\xde\x92\xefM`\\{\x91X\x1e\x043\xcc\x8a\xe44]O\xbb\xdc\x84\x8e\x82\x83B\xb9\xf3U2\xefi\xffU\x013s5\x05V\xad\x03\x0f\xce\x88=[\x93\x91\xdc\x04\xdfp4\x0b\x85R\x81L\xf53\xa7\xf1Bp\x86(\xda\x1a\x10S\xa0h\xd1\x06\x8d;\x83\x02,o\x19\x9f/\xca\x19H\x93\x92#v.\x15\x95_y06\x93{\xe5\xb4\x83|pV0\xf3\xc7\xc7|\x96\x92\tsvP\xfbKjt\xb2\xfdU\xc0\x8b^~V\x02R\xfd\x8c%\x7f\xdb\xa3\x0e<W\xf3\x9dT\xc5\xb8\xeeHlQ\x1bEV\xbc\x7fC\xaa\xe8\xf2\xa4a\x83\xa7\x80\xd2\xbe\xa2\x90\xd7\xb0M+\x9f\xbar\xd3uy\xc4\x83\xb7\xe6\x8f,,\xc06c\xf7x\xd4\xfa\xb6\xd8K\xe0\x91\x84\xfb\xb7\xef#\xf3n\x91f>T\x17\x85\x8et\xd3\xc3\xdd\x87\xb8\xf5\x88\x17/\xe5\'P/\xfa5uMZi;\x03\x1c\x9d\x88\xe5\xc5\xbe\xef\xdc\xa5\x87\xcfG\xe9\xd8\x91\xc6>\xd2\x90\xb5\x1d\xed\xdf\x10\x8c\'\xce\x87\xd0<\t\xf8\xc2}\xee\x18\x95\x93\xb08\x8c\xdc\t\x84\xd6.\xf0lOL\x7f\xc6\x17\x82\xb7\x1e\xa6\xf0N)\r\xf9\x94\xf1QB*\x0f\x94\xa1\x01\x03\xc24\xc8\xae\xa1k\xab\xe1?\xdb`\xe26\xb1\xb2\xc2kU<\xacgO\xb5\xd9\xc6\xb4\x10\xa2\x00\xaa\xb6#\xad\x824^N\x97\xc3\t\xfab!\x90.\xc8c\xfc\xa9\xdf\x8d\x8e\xc2\\#1\x0eM\xc5\x18\xd6q\x1aO\xe6\xae8\xee\xbd\x98\xc7\xb3\xa1\x89\x18\xd9\x89\x18n\xa1\xbdP\xb1\x93\x80\xa7\x00\xbd\xc0\x8c\x8b\xd4\xea\xc7\xc2I\xc5\x1c\xfaF\x1c\xc6\xb5&\xd47\x1ei\xedY\x98\xc9\x1d>\xb6s)6K\x7f\x87\xb4\xa6\xfej1/\xa7\xd3n,O\xa4@\x19i\xf88\x90\xdat\xc4V\xe0\x1c\xee\xc6\x07\xfd\xa0<\x07\xde\xc4\xf8j|\x8a\xc4fa\x19w!\xa9J\xc1\x93\x96\xa9\x16\x94\xe7-$M;mD"\xa9\xa9\x10\x13\x06\x05\xee\xac\x8e*\x07\x99\n\xc2;2\x12s\xaf4\x1a\x10\x18\x14&vC{Cs\xf4\xf3\x9c\'r\xea\x1a\x04\xc5"7\xcax\xdd\xfa\x92\xa8\x87\x1b\xa3\x8dOn_y2\xca\x87[\\i\xa0\xd8\x0eZ~\x89g\xfdRamq\xf4J\xad\xfe\xd3P\'\x9aH\x867m\x0b\x1e\xe3Z\xc3\xf7\xe8_W\x90\x1fd\xc7*\xac<\xa2|\x06\xd1)\xbfN\xcb6b\xcd\x83\x8fL\xae#\x9cO+x%\xe4\x92\xa0CS\x12\x05\x19\xeb\xb0\xdf\x19O\x88};\xf7\xc4\xceW\xc7k\x82R>\n\xd5^\xc9\xbb\x82\x82\xeb\xa8\xa5<FL`\xb1JT\xe4\x94"\x1cgJ\xb9+3\x14c\xd4\x1fK\x879\xd6\xe2i\x06\xa1~?h0S\x96\xe1\x88\x81;\x84\x85v\xbd\xc5\x83\xe4\xc0\xae\x9f\xbc\xf1\x1c\xf2kR\xec]I\xb1\xcb\x97\xd65oS\xff[\xb3\xec\x12\xf8\xcc\xaa\x9c\xcf\xf2\xcby\xdf\xe4\x9c*\xab^\x02\xb0\xa7\xf0\xd2M`\xc1\x12c\xac\xd7i\xed\x95T:\x04\x97\xde\x82\x9bOcTv_\xdet*t\x07\xbe\x1c\x85J\xf9\xa8\n\xe9\xbeMh&w\x18V\xde(\x0e\x05\x05\xf6\x95\xc8CE:M\x0b\xefiC\t\xfd<\xfdR\xe1\xc5\'\x0e\x12\x91\x86\xc33\xdab\x8a\xb8^\x00\x04\x18\x7f\x81;\xb4\x11\x13Yb|\x1d\xa3"\xec\xf9\xe0\x1f\xa48&Hq\\\xa6\x988_\x8e\x9c\x94)T\x7fHqJ\xa6\x98\xfe;)\xfe_\xffFRt\xfaOR\xa4\xae\x0b\xc8\x9fE!y\x9d\xf5U\xf8O{\xbcyd\x05\x1f\xd3t\x89\x0c\x01\xf6\x9b\x8e*cX\xed\xfa\x80Vn\x8a\xd2Jj\xba j\xe6i\xcb&\xfe\x91Kv%\xb2\xc4\x1a\xa0\xdc2\xb7&\x99\x88b\x86\xb6\xdcL\xb8(\xcd\x8b\r.S\xb7\x93=\xe0.Kt\xe0#\x8a\xa5iJ\xc425\x85\xc3\x9c#\xba\xdc`\xfd\x12yb\x00\xad\xff\xf2\xc2\r\'\n\'q\n\x88\xa0\x1aEz\xb91\xecZ\x9d\x9f\x03\x8b\x1e\x15\x08\xc3\xf7\xd1\xae\xaf]\x01\x9e\xef\x00Rh\xabB\xc3\xdaE\xae\x12@;\xb8p\x1d\x9c>\xf7=XJ\xff,!\xde\xd6C\xb8\xcb\x9e;\xdf\xa2Q\xed4^)$vf\xfc{\xa1\x84\x05\x1d(\xed"\xe4\xd4\x1b\xc8\x93O\x1d\x10F\x9b\x90.G\xd2^\xc0!Zu\xf2\x90\xe6:\xe3\xa9!D\xe41\xdc\xf2\x8c\xd6\xddI\xd4\x8a\x1fI;\xbf\xc6\xa1,\xcf>Z\xd2\x98\xd4\xce\x13\x08\xbb\xe6\x10>\xces+\xe7\xd1\x020$\x92P-\xe0\xe9)/\xbc\xa2\x06\x89\x00uh\xf8\xad\xeb\x0bD\xa6X\xbdo\xe5\xed,Q\xcc\x86w!\x9b\xac\xa2F\xa9\x04\xd4\xdb\x00\xf2\xba\xe3\tFk$\xcc\x17\x8di\xe3\xde\x17v\xb4\x9cGCvRa\xcc\x1e\xf7h\xd3d*Z~\x98\x92!\xa6Lg\xd1\x98mnyL\xcb\x97\xc5\xd1M\x18\xb7\x99\xb4\n\x05\r\xdc\xe2\x0es\xf8\xf4\x89?\xc0\t\xf9\x81(p\xf9J-\xe1\xe6ee\xd4c\x82\xce\xaf\x03y\x07\xee\x03X7\xa8\x97\xc7<SE5\xe1y\xfew\xfd\x1dO\x97\xe6\x97\xcb\xf9\xb8BT\xb1\xf3j\xae3`j\x94v\xb5\xa4\xb3\x89h\xc7:\xbf\xe8\x13\x02\xfb\x88\xd7^\xbcy\xccbo\xde,,;\x81\xffVx\x134\xac\xd4C\x9f\xd6\x1e\x94\xa1\xf9\xdd\x19\xdf\xf94\x85k<^\xa2\x93\xa3\x08\x1eiv\xba\xeb\xeds\xe5w \x8e\x07^>\x85A\xdd\x05\\\x0cPSV\xb0\xe9\xf9\xd9D\xd7AR;\xb4\x9f+6\x19\xf0P\x9cwaz)\xae\xd8\xe6z\x1f\xae\x95*A\xe3\xaf$\xd1i\x18M:\xdc(\xe3\x1a\xee\x8e\xb1\x16G\xe0@\t\x8d\xdf\x95\xb6@\x1c\xbcE\x80\xaf\x04^s\xc0\x10M\x14\x00\xc5\xfa\xf3\x85\xdf\x99\xe7\xf3\xee\xd5\x0c$\x1as<\xe6\x93o\xc0\'\xc8Z\x1ec\xd0;i-\xc1\x88\xf7\xa2^KI_\xaa\xc8\xf9vE\r\xee\x99\x8d\x1b\xf8h\xd8\xf2)\x0f<\x86e;\x1f\xbd\xe51\xa5\xed\r`\x85Zl\xea\x15U9\x99\xf0\xfc\xfd\xafq|\xe8\x89x\xdf\xf7r\x16\x06\xd2\xd7\xe2-#\x9a\xb0\x95v\xc3\xee\x81\x8c\xa6-\n3y#\x84\xfb\x1f}\xc2\x03\x04EK\xb5\xb6M\xa2\x82\xcd\x1c*\t\xd1\xd6\x9aJu\xb7!\xeb\x9dY"\xc90V\xe7p\xade\tm\x95\x1bE\xc6\x03r\xfb\xc2\xb2i:\x10@\xde/q\xdc\xe9E:\xb2\xe6\xb1\xd2D?^\xb9ZB\xf5\xa2\x96x\xf1\xbc\x12&\x03\xb6?\x12\xb5\x85\xc6\x18:\x91?\xb6\xc36\xfdF\x89\xa2z8\x9eZ<\xe4|R\x9c\x99*\x0e\xd59\xe5\x9dg\xbc\xe5/\xbas\xeb\x19\x18s\x9f\xd6D\x03\xd3},\xbc|\xa83\n\r\xafCk6D\xc5n#\xd5\xdd\xa3\x91P\xb1\xfeW\xe9\xeeB\xcb\x95\xf0\x94\x15;{j6@\xaa-\xa4\xcc\xcd\xebRq\x81[\\U\xc0\x8bXZ\xf4\x02\x1b\x9f\xc4\xf1\x80\xed\xc7\x0f\xd4\xedq\x13\x113\x98.\x8e\xa8\x18\xe3\xea\\\xde\xbd\xc0m\xc5\x10\x08g\x85\x88\x99i\xab\'\xaf?\xe3\xf3\x1a\xda\xbb~\x07B\xa1K\x80\xea\xb2=\x9cB\x9c\xed\xb0\x98\x1cu\x99O\x1fH\xbaf\x1f#\xbc\xc6-\xd7\xcd%NY\xd7\x86\xd3\xa9X\xfd\xcb\x00\xb7\x1cP\xd7e\xc1\xce\xd2AU\xd5\xb4\x93N\'\xe0\xb9~\xa8\x92#n0\x88\xbb(\x08\xd0\r\x9d\x10\xe5\xa33oiB\x19\x1d\xc1\xdb\x97x%\x06\x12\xab6\xcc;\xe0\x93\r\x06c3\x03\xee\xfb\x1bq2\xfd\xd8\x12L\xb3%Tr\x1a\x8b\x15\xff\rQs\x1b\xfa\x03\xc4\x9c\xe9\x7f+\x0f\xe0\xd3\xf7\x8ek}\xc3\xb8\xf9\x87\xbf\xe0\x08\x13j\xb1\t\xca\xa0VK@\x84\xfa\x168o\x9e\x07\x0b\xa4<2\x92T)0\xf3\x9e\xebg\x16Uw\'\xc6,Jz\xeb3\xc3\xa9-\x1a\xca|^t\xa1,\x93E\x96\xd7O\xa3\xf7\xc4=!\xa2\xba[\xec\x06\x18\xd3\x07\x06t\xf3J\xe2\xdb\xa7h\x0bX\xaa\x8f:=D\x19\xd4\x0e>=\xa3\xa3|h\x9bV\x9bXQ3\x9a\x025;\xf88\x84\xd7~\xa0\x8f]\xd6v<\xe6F\x1bVq\x12\xaf\x01\xc6x9\x01\x80\xb3\x1a\xc1K\xde\x96\xc9)\xc6BcRK\x08\xd4\xcbL!\x14o+\x82lYT#\x88\xa3\xef\xec\xc46\x93#\xc2gf7!\x13\x87x\xa1\xc8\xbc\x94w\xb2\xa4\xc2\xd8f1\xc9\xb5\xcas\x960\xc7\xceSet4\x0fK\x1cih\x0c!{r\xbb(\x9fN\x95\xb4\xeb\x02q\xb9k)\x951\xcd\xbe\xa2\x85+\x96B(\xf1\x99+\xef\x04\x8b\xd2\x9e@t%\xb3\xec;\x92^M\x02D\xcctjzi>M8^\xbc\xf0\x19\xa4\xd9O\xddW\xb3\xbfq\xdd?HrF\x90\xe4o\x99b6\xa4K\x90\xe4\x9cL1\xff\x87$\x17d\x8a\xc5\xbf\x93\xe4\xff\xfdo$\xc9\xc7\xffJ\x92\x97\xa1r\xd4\xf4[\xab\xf2\x11\\s\x1bC\xb2\xe2H\xc7Q\xb4Qa\x8d\x1eo\xe6\xc7q\x93\xc3\x15\x93\xc2t\xd6(\xa86\x9d\xdb*\x08\x06\xa7\xd1T>3\xc8\xa7\xe3*\x8c\xd4\xbe\x96D\n\xbc\'&\xe6\xe6\xfc+b\xdd!\xa1\xf7\xa8_\xf1\x95;\x82h#\xd9\x89\xff\xaaEmD\xd3:*hF\xecU\x1fFT4\xca\xb9\xd3:\x03ZM\xe3JSR\xeeg,\xb6\x07\xec\xf3|\xb1\xaf\xa7\xb6\xa8\xa4\x83\xd4W\xd1I\x9a\x8b\x93\xd9;\x01Y"\xbd*\xa2#\x80\xd8#V\xebf\xe4\xe6 \x89\x1fp\xe7\x05\xad\xbf\xb6\xfb\xf5D\x89m?\x0e\xf0\xfd\x01 \xfd\x81c2\xe4\xde\x107]\xf5\r\x0c\xb3\x17\x88\x16)N]\x9b\x07\xc6\x1f\x95\xd2\xce\'\xb8\xe3\x06\xd8k\x04\x88\xb2\x90\x9dg\xf6\xf3\xfcD:CS|\xde\xc4G\x06\x08\xa5N7^\x8f\x03\x1d\x9e\x96\xbd\xe4\xa6\x87\xff\x91\xdc\xd5\x9a\xf0\xb1\x9c{J\x11\xa6*\xb4\xa0\x03*w\x8a\xea\xf5m\xec\x10v\x9b\xe2HG\xdd\xf0G\xf0:\r\x1e=v\xdf\r\x10\x08\x01\xbf\x01\x8dVy[\xa4\xb6R\x8d`\x8f6\xd0\x1c){8\x8b\xb6\x8aj\xc01\x04Q\x0bb\xb2\xd6\x8b\xc7E\x0e(\xce\xddk\x94\xb6"\x9e\x06UJ\xf0w\xc0\r\xd7\x91<\x0cf\x01\x11&\xa8A*\x12\xf5\x135\xa2\xd4\xa5\x95M\'~\xa0\xd0\xa6\x0c\xde\xd5O\xa1\xc3\x1f&\x80\x8f5\xa4 Fz\xa2\xca\xad\xb2\xac\x18#\xbbE\x07!\x17\x9f\x01\x83:\xc5Qq\\+\xe6?\x95>.\xa0\x86q\xda\x88\x8e\xe4\xceB\x1e\xf9D\x83\xc5\xd2\x94Z\x83#.X\x10\x18\x9f \xfcb\xcf\x1d\x9fm\x04\xd8|\xe7M\x07\xa5\xa8\\\xe4\x85\xaf\xbe\xa2\xfa\x98\xd5\xc5\xd64,&\xfa\xbah\xdcL\x97\x9aK\xf3\xe1T\xed\xef\xc0\x83;\x08\xe7\xbf&b\x81\xca;\x10\x0fnw\xb8\x81\x07u\xd1\xb2\x13\x934x\xc5\xf6g\xa4\xfe\xd5\xe7\xaa#\x01=ly\xeb\x8a^\xf6;\xb3\xaa\xf260u\x8d\xa7>_\xbb\x18\xf8\x10\xfe\x8c7\xbe\xa1a\x7f\xbc\xe4\x88\xd4\xee\xc20\xd9\x81\x00\xfay\xe3\xf3L\xf8\xda[\x1f\xd6\xbc\xfa"\x97\xb2\xa4\x130\x074\xdd\x19t\xd7\xf0}\xb1\x17\xc2I\xd7\x16\x8f\xd8p\n\x822X"Q\xc15L}\xe2\xfc\xc4\x15\x9e\x81Ufo^\xe6\xc3k\x0fC\xd1\xd4\xc1\xb4\x1f<,G\xab\x1b1\xfa\x0b)xtO\xa04\xffI\x1b\x06\\oO5\xe0\xe6.\xa5\x07pb\x13OZ\x10\xdbm\x05^\x0e\x01\xbdzY\x12\xd9"%\x04g\xc3\xc3\xd5\n\xb4z\x1d\xde3\xca\xa0\xf8\t \xfaJ\xc0y\x8d\xa88+\x88U\xbay\x02\xf7\xfde4\x9b*\xb6\x19\xcb\xa9\xe9\x1d\xbe\x96\x98\xd1\x0f\xbaAl\x1b\x02=@du\x07\x1ag\xc5\xf90pU\xf5Wi\x8c\xaf\x95\x88\x1e\xb1\xd4\xa9\xcb\xeb\xd7i\x0ba\x19A\xdb)h\xf7\xc6{\xf1\nj\xf9a\xc9\x1d\xf1\xe2\x88\x9c(x\xcc*/<\xc6\x18\xcc\xbd\xa0)9o\xfb\xa7\x07\t.G\nr\x12\x07\xf7_\xa4\xc6\x98D/\xde`u\xb96\xd2C\x19\xd2C\xcf\xf8\xa8o\xb4)\x95m\xecg\xea\x9ar\xe3-C\xdf\x9f\xa2\xba\xca\xfam\x8ck\x18$f\xa0\x82{\\\xcd\xb3i\xcd\x84\x8e\x13\xf5u\xa9\xd7S\x9cO\xa5\xc8\xf9\xfc\x02\xae\xfc[\xaa\xc9\xdd)\xb0\xe1\x85B\x9a\xb6\x94\x92\xc2\xf1\xd7\x9fiLN\x83B\x87\x88\x9d\xe8\x07\xdc\xaaL\xe1M[\xda7\xe3\x9a\x87\x0f\xc0\x97H\xfa\xde\xc1R}<\x9c\xc5\xe2\x88\xa1\x06>\x89qGhI\x15\x93\xd9A\xe2$\xc7I\xfd;\xd9\xac~T\xc8\x1d\xaf\xcbn\xd9!\xa2v\x0c\xa5\xed\xf8B\x03\xf6\xeaK%\x99\xcbJ\x9a\xbd\x0bB\x11\xa7ut:\x05\x889sj\x89\x14Gn\x05\xc3\xd3\x9a\xbc\x1eF\xd1,\x9d\xd9\x83\x18\xd6\xcdY\xfd\x8e\xf6\x1dtI%\xb6\x8e\xa9y\xc4\xaeD\x1f\xf8\xb4\x9b"\xb6oQ\xb3\x07W\x87\xd1\xae5kr\x1e\x83\xa7g\xf9\xc8%\x03q\xb3\xc3\xbdp\xea6;\x7fc\x89\x83\x07\xec\x93\xd1\x95\x81\x08\xee3t\xe2u\xef\xaf\xb4\xf9 .\xc6\x8dE]\xa9\x9a\x17C\xcd <\x1a\x801\x1b\xdc^&\xadXr\xebG^\xca\x00lb\xe4;\x83a\xa5\x9eO\xb4(q\xd2\xc2e\xd2\xf8=\xd3~\x05t\xda\x11sg\t\xdc\xf0\xa58\xe9\xd2\x95D\xdf|G>q\xe4\x89r\x0c\x86\xd0\xe9\xc7b\x11\x11\x00,\x0ea\x9a3\x15K\x00\x07\xb0\xf90\xd2\x9a\x83\xc8|i\xe3\xc5~\xa5(\xc6\xe5\xf5\x97t\xe4\x06Sl\xd3Y\xa9\xd8\xcaX\x9f\xe9\xea\xcb\x8b7ISD\x03\xa9<h\x19@+Y\x0fy\xf9\xc2\xed\x1b\xf0\x8f\xdeJ>\x8e\xe0\x198\x8f\x98NA\xc6\xb4\x04$j\x01#\xc3\x92\xb3\xbc\xf3\x99\x8f-0\xfe\xf5\xf0\xf6\x19]w\x90\xacXn\x84\x97NTr\x9d\xb1\xa4\xaez\x959`\xe0\x95\x0fbR\xd8\x19#\xf2\x1b\x88\xdc\x82\x88^F[Vc\xb8\xcb\xd6B\x88\x02\xe7\xe0\x12\x85X\x16\xceU\x8a\x93\xa62x\xfa\t\xcf_x\x88\xf6\x8fQme 5\x9a\xff\x830\x97\x04a.\xcb\x14+!\xcd\x820We\x8a\xb5?\x84\xb9.Sl\xfc\x9d0\xff\x8f\xff\x9a\xdd\x91\xd4e`A\xd3\xbcy\x9b\xba=\xab\xe0\x9e\x0b\xd1\xd0=\x13b\xbf3<\xf2\x94k\xdc\xe9,\xe2R\x80\xd8L,N\xc0\xd2(.b\xd8g\x0b\xbd\xc3i\xd0[\x9fFr\x9f!\xeeZRu\xces\xc2;ba0Dl&X\xe6\xf57t\x90\x0e\x9b\x8d\xe2\x99\xe3\x99!\xe2\x14\x0f)\x85@\x026\xed\x80A\xeeJ\x06 \xb4\xf3\xc637\xe9x\xd2\x13H\xc2\x05\xda\x1150\xca\x1bbG\xe0\xf5\xeb\xcah8V\xa71-\xe6\x8a\xe34Goz\x89\xed\x80JqZ\xda\xa8\x7f\x95\x98\x19\xcd\xe5f\x0c\xc8\xa6\x19\xad\x05Q3\xdaq\xa8Om\x12\x1e\r\x88\xea\xcf\xfbUEx!BI:\xf4\xa4\x19\xe03_\x19^t\x0f\xf2q\x1e<\xa1c\xea\xfcLL\x17\xd1\xe0{\xb1\xbe<f\xff\xd2\xc2\x97\xd5\xeeF\xe7\x87\xd4~CBH\xaa\x88[n\x8e\xe2\xd4\x15?>I\xa6\xb3\x12j\xe7\xdaO\xe7\xa4i\x96\x88\x17nf\x95\xf1VPb\x12\xbc\xa7\x16Y\'8\xc8!\xc5\xfe|A\x904\xc8|^\x83)\xc4r_k\x18\x9d\xf8\x17\xf0\x80\x0b|\xa8U\x1c\xe7B\xad\xd2\xa6\xc0\xe44>\xb5\xa1\xbeo\xdc\xabu+"\xe0\xaa\x8d9o\xdd\x12\xe7\xc9\x020\xe3o\xd0\x80y:\x02\xb5\x8f\x1bn\xf3\xea\x0b<i\x1f\xe01I\x83\xfa\x85\x7f\x16\x03\x03\xc5\x06Mi\x81\xf9\x98D%yk\x8e\x17\x12\x96\xe1\x1f\xf1\x88\xe8\x95\x12\xa1P\x9c\xde\xf3\xfce\xb1\xe8\xe2,\xa7\x81\xec\xc2\xb7\x80\x9ej\x86II,\xb5nJ\x07\xf5\x19\xa1\xf1k\xa5/y3\t0\xd1\xc2uJ\xae\xd7\xe3\xc92\x0c\xc9\x18Z"M\xdc\xb9At,\x99\xdb\x8b\xcd\xb0\x8d\\\xf7\x19\xe40\x10L\xf3\x11Qy\x17\x9e\xe6"\xc5\xd8a\xe9\x08\x87\xc2"\x1f\xda\xcc\x83\xe3\xb4\x03\xe3E!\xef\xef\x00)#T^J\xa2q\xdf*\xae\x03\xe6\xf4\xf2R0\x89J\xa9V\xd7\x10\x80\xfa\x88\x91\xb4\x81Os\x9f\xc4\x01k\xd317\xbc\xa3\xa9\xbe4(\x93\x9bq\xf9]\xa7\xf3\x1d\xf1hV\xb58Ml\xd0\x11m>\x03\xd0\xf5\x89\x82*\xea\xc1\xc0\xeeKs\xbe+\x82\x11\x95\x86\xc1\xdc\x1a\x85\x9e\r\xfc@f\xb7\x84\xcb4\xe2\xb0\x9c\x1c\x0c\xcb\xd43\xa9<T\x87\xea\xae\x82\xde&\xa8+\xc3.\x9e\xb6}\x12\xd1"u\xe17\x9e\x0b??\xb3vC\x1b\xdc\xb9\x07\x9e\xec\x8b\xfb\xc1{WI}7>>=\x9c\xb6\xa9O:\xaev\x8cj\x02\x80\xfc\x03\x8fx,\xf6\xa6\x93\x87\xf0\xb8\x03\xbc\x1c\xbc\x13r\xce\x81Nb\xf3\xfe\x19\xd7%\x96\xb9\xd3R~ja\x08\x90z\x89\xd5~b^\x945E\xc8\x86E5R\x9b\x0b\xb5e\xf2\xefW\xe2\x00#\xe4GCr+)7D\xc4N\xe8\xf8\xa2\xcd\'YF\x18\xdeU\xfc_MM\xf9\x86\xa2\\\xdc\x92\xeb\xd3\xf3\x9dDB\xdc\xca\x1a\xab(:\xf4\x17|t\tC\'&\x16\xb5\xc4\xe4\xed\x13q\x06u\x0b\xed\xa6\xd3\x96#\xab\xbe\xb8\x88*\x80\x1cG\xea\xb6\xb6\xbbI\xbf\x1d"\xac\x93\x10i#\xdfh\xe1mR,l\xd3\xc5\xcb~\\S\xe5j\xfbVl`$\x8c\x86a\x10i\x9c\xe8\xf0\x17\x89\xe3\xd7&\xd2x\xc5\x06\xd9a\x96\r\x02m-\x06\xf6^\x81f\xdb\xc0mC\xb9\x92\xc4\xe8\xc0\xe3\x8f\xd3\xf5\x0c\xb9%K:\x15d\x98\xea\x8c\xbd3\xdc\xc2\x8c\x95\xb0\xc3J@P\x90\x9d=\xd8\xedjzPN\xf4g\xdeq\x8b\x16\x9b\xda\xddK\xa1\xbc\xe6o\x99\xf2f\x89\xbe\x8d`\xed!n\xb7\xb9&\x8a\xb6\xedc\xae\xd3vI\xd8G\xda\xf1\xf7\xa7\x03\x8f*9\xd8e\x90\x97\xef\xd2\xa0\x0fu\xe4\xc3\xff{\xae\xf2\xe9\x1dc\x0cL\xff\xa7\xef"\x17\xec\x83\x8f\x8d\xe4\x88"$\x80\xc8\x04\xd7=\xa0\xce0\xe4r\xf3w\xe1`\xf56T\x17f^\x8c&N+\x83\x10G*\x9a\xf7s\x01\x1b\xce\xcbh\xef\xf5Gt\xe5\x10\x83\xbc\xf1\x06Q?Kb\'\xf6\xef\x17\xac\tK\nF\x87\x0e\xbf\xbd-\x90\x89\xfaB\x90R74\xe8\x8e\'\xf8w\x13\x01\xd7\x88?:h\xf4\xb2\xbe\xf7e\xf1\x9b\xb7\xcc\xea\x81\x82\x0e\xe5\xd1\xf6bGL\x89 \x81\'\xbcDC\xdf\xe1{C?_=\xf8\x81g\xad<<?\x13\xae/!\x02\xef@\x04\xc3_O\xfd\xa9S\x81\xfe\x8e\xbd\xa1S7\xb8\xdbv:-\xf8\x85|\xe4=\xdd\xa0\xe7\x08\x165\xd5\x97\xc8K\x9f\x81\xa8Z\xfdHc\xa2\xb8\n\xa7Z.\x83+O\x96@\x98k\x97W\xa2i\xad\xba\xdcU\xec\xcdG\x9fy\xdeBZ\xf4\x9c\x15ed\x88\xd4\x13\x87\n\xa0\xca\xb6t\x92\xc4\xe0m0\\\xa3\x95\x05\x86*\xac\x84\x1a\xd2\xe3\x91 \x883\x0cZ\x0b-D5,\xb7\xfe\xa4\xa9\x87<\xfb\x92\xce\xa86\xf5c!\xef\xf2\x90\x1f\xf5\xd2\xf9\xe6\x8fy\xcfr\x01s[\xba\xd6\xb0\xf2\x19\xee\xaa/\x96\x0e%\xf0`\xb1oW\x9c\x97LG\xe1\xbc\x16\x18\x00\xbcY\xfc&\x11 \xd5\x9b^\xb5\x8f\xfc\x91\xce\xcbU\xc1\xd6\x89\xbe\xd2Qu/\xc4\xeeL5\x0c\xb2\x89\x7f\x81\xbb\xcf\xech=\xeb\xe2\x05\x12\xe714#"\x0f\xb9\xf3\x16\xb7\xfd\x83\x1a7\x055n\xc9\x14\xdb\xe7\x1b#wd\x8a\xdd?\xd4\xb8\'S\xec\xff\x9d\x1a\xff\xe7\xbf\x91\x1a\x9f\xfe+5jq\xe7C\xda\xba\xf3\xe5\x17\x14\xb2*:\xe2\xd6\x9d\x0f\x16\xc1\xdeI\xa4\x16\xcb\x0cw\xaf\x88\x93\xdb\xc5\xc8\xfc\xbe\xf04\x83\xc6\x1e\x81W\x0e#h\xceD\x1fbo\xf3\x13\x14\xe4\xb4\xd0\xea\x90\xc1\xe2T\xf9;^\x08\x96\x1d^vK\x05\xfeM\xb8\xba\xf3R\x1c\xe0\x18T\xa1\xf4*\x92\x1bj\xd1\xf8\xadT\xda\xa8\x82#\xd7\xf2\x01\x80\xec\x99\xc2\xe9<\x07\xfc\x82\x14\xf0~<\x9f\x86>\x12\x1b\x05h\xc5\xd0K\x12\x9c\x9d\xbcx;QZ\xd9\xd1<p\x93\x938\x0e\xa0\x8b[d4i\x1e\xcf\xab4e\xc1\x9b\xde4\xa5\x7f>\x03\xaa\x17%Rx\xb1\x9f\xcc\xee\xf1sg\xda}\xf5\xca\xe62>W\x81\x89\xa5\xcaV\xb7`\x9a\xfe\x16O\xf3\xae<\x98\x89W,F\x88\x12\xaf&\xa0\xcb\x125\xc4\x82q\xcd\r\xa8\'\xfe\x95\x96X<w\x80N\x1f\xf5*\x85\xdbm\xc1W\xd7h\xdf\xe3\xaf]\x16\x8db\x03\xc4\x16\xed?,M\xc2\xcb\x1a!\xe04\xb4b\x008\x11\x05\x8c3\xe7\x1b\xb5\xaf\x01\x86\xba"x\xfd+\xf7\xc6)@\x99\'\xb6$&u\xd7\x04+\x8cK\x05N4\x95\xc7+\xd7\x1eW%H\xcd\xdb\xa6\x83\xf7\xb2|\x9eG\xde\xb4\xf7\x17\xe9\x89sXj3\x11\xfajY\x0c\x1f\xe6%\x04C\xde\xd5\x88ex\x95t\xfe\x8dT\x00\xe3\xfeK\xda\xe7\xb2\x85\xdb\xea\x92\x9d\xecX}\x95W=i\xe2\xab9U\x87I\x9b\xf9?\x00\xc6\xba\x03i\x81f\xde\xde\x85\xa4\xebL\xf7\x89\xb7\x07\x8cJ\xdb\x9e\xbep\xb5\xe3\xe5|\xc0ss8\xad\\G^\xa9\xe2\xf5t\x04l\x0cO\xb9\xde?\xdf\x06\xc1\xd3b\xfes\xa5\x08\xd9H\xad\x81\xd8\x85\x03;\xaai\xc8;\x08M\x98.~t\x03\xca\xdcYtX?XL\x13\xc1\xdb:\xb83\xb1\x80\xbb\xbd\xa1v\xdb\xcfw\xc3\x07\x7f~E\x1b\x1f\x00\x15\x8d\xc0\xd3\x16\xdbR\x03\xe9\xa0\xd9^\x1a\x8a\xf9+\xff\xd3}KkO\xf9 U\xa8\r\xdfh\x91C\xe3:\x91\xfc\x97X_\xd0\x83\x82\xadF\xf0\xafC\x94\x8a\xd3\xf9\x1b\xca\x81\xe2\xb5\xd4 \x94\xd5\x993\x9f\xc2\xf3\xdc>\x90\xbaR, \xc2\xd76xQ\x1b\x0fW\t\x18p\xe3\xb5T\xea\xba)\xecD\x9a\xab7,y\xfc>pc\x1d\x96\x1b\xa1\xae \x84\x86\xe0\xa2\xdd\x8f<r\xe3|\x83 oIa\x03D6\r\x11s \xbc^J\xeb\xe5\xe2\xc0\xd2#\x9e|\x06b\x12\x12\x02\xec\x8bf\xf6\x94\xd3\xf6\xa7|_\x93\xe0J\\6\x83l\xb3\xee\xad\xb4C0\x15&ov\x00\x07Bb\x06\x98\xb1\x98\xa1+\xe6NK\xee\x14\xcc\xa7\xe4:]ns\xf7\xc9\xf4\x8b\xa5\x9dh>\xd4\x8b\xa4I;\x88\x90Pi\xb6u@\xd4\x11]\xa9H\xa4c3\xab\x92|QV\n\xc4\xdfx-\xf6\x08\x9co`\\\x95$\xca\x0c\x9dVR\x8b\x15w>\xa1\x15\x9fr\xea\x7f-\xa6\xed\x1f\xbe\xe71O\x0b\x88\x93\xa9\xf2\xcc\xb0\x14\x88\xd0\xc5*\x1a\xb7\xa4SS\xb1\x1f\xde\xd3?\xcd\xd5\xf0\x07\x1e\xb6J\x8bn\xe2\xc8\x1b<m\xdf\'\xd4\x05\xae\xd6\xfd\x80Z\x1e\x88\xd3\xbf\x06c=\xa9\x87\xbaREy\x0e\x04\xe4\x81\x1e\xaf\xbc\xe2\xbd\xcbw1J\xbd\x97\x91\x1b\xd2\xf8\x13\x9a\x08\x87[\xaf]F\x0f\x97\n\x85?\xdb\xfd?]]\xfdKSa\x14\xce\xb4\x14\x7f1\x10SSq\x95\x0eDs \x84\xce\xb4\xb0\x90\xd6B\xda\xde@\x1b\xf8\xd1/\x17\xbf\xd8\xe6\x1c\x95_H\xe4\xb4\xe6\x98i\x98\xa2\x90IVK\xf2*~\xec\xba\xcd\xab\xc19\xffX\xcf\xb9\xa3_\xe2\xfe~\xb9\xf7=\xe7}\x9e\xe7p\xce\xfb\xbc\xd6\x99\xcd\xa3\xbb2\x03cT\x95P\x1c(\xbeoU\xb3]t\xe1\x1a\xf0\xe6L\x90\xd9nC-\x13\xef\x05j\xbc\xb3\xb3\xe1A\x82\xc4\xda\x10\xa9\x84\xef\x99\xad\xa4\x10z.%\xfa\x05\x8csl\x99\nn\xc8\xf9VM\xcch)s\x85\xd2\xf9\xb4\xac(Z\xd1\x8f\r\x0f\xfd\x90\x94&\x01\xd6H\xa7\x83\x17\x08\xf5\\\xc3-~_\xe6\x0cUAy$\xfc\xe3\x00\x9b-\x0f\xfeq\x81~\x87\xc9\x08\x82\xf4\x87\xc1\x00o\xe9\x93\x1dT\xbe\r1\xbe\xd6\x80%\xdd\xc1;b\x0f9\xddM\'\xbe\x0e\xda\x9cu\x8c(\xda\xcf\xfa\x82\xc89p\xf3U\xb1v\x996\x9c\xb5\xc5o\nx\xa9\xb65\x9f\xcd\x07\x9c\x08\xf2\x1a]\xb4+\x04\xfa\x83t"V\x8b\x9eZN\xa4\xf4g\x943n>\xf6\xd1\x8a\xa3\x9c\xf6\xdc}Z\xb6\xae\xe2_\xd0\xf9\xe7\xfcc\x86w\xbd\xf7x\xab\xba\xb9\x95v-kQ^FFl\x96V\xd6\xb9f4\x99\x16<\xb8j\xf1\x9a1\xe4\xba?\x80D4\x02\x14U\xd8T\x11\xfeR\xd3\xa2\xd8\x08\x03\x11\x16\xfa\xf8\xf4\x11\xafO^\x7f\x9d\xd7#\xbdI\xb1/\xb1\xae>x\xce\x9f{\xa0\x0c\xf6\xee \xd7cY6\xab\xa4\xedig\xb8\xc3\r\xfc\x89>\x99\x02R\xe8R4\xca\x14\xe5\xa2\xc7\xe1\x04P}\x041\xeb\x9d\x80\xed\xc8(J\x19{\xb3L-t\xa2>]\xf1\xcb\xd7\x89{\x81\\\x90\xd1\x0f\x92\\\xe5\x9d\xdc\xe0K@\xcd!E.a\x83\xfe\xbc\xd1m\xc3\xce6\xc5\x19o~\x0c\xb9}\xc4\xa9i\xef\xa0\xb4!\xaf\xd5\x90ni\xf2T\x13\x94\xfe\xb7\x80\x8c\x13q\xf4\xf6\xcd::\x9bEt\xbf".I\xd4$\xeb\xac\xd7\xab@o!xq\xe91\xc7\xfd\x08\xc9w<\xc9\xffh\xf1Th1\xa5B\xe9\xaeE\xa1\xc5\x8c\n\x9d\xfd\xa3ES\x85\xce\xb5\xc6\xbf\xa4\xdf\xca\x0c'

解法

出力結果の行列の一部を R = \left( G + G^ \mathsf{T} \right) S + H とすると、以下のように式変形できます。

 \begin{align}
R &= \left( G + G^ \mathsf{T} \right) S + H \\
\left( G + G^ \mathsf{T} \right) S &= R - H
\end{align}

 S, H, R  0 列目を s, h, r とすると、さらに \left( G + G^ \mathsf{T} \right) s = r - h というように式変形できます。

 s にフラグの情報が含まれているので、上記の式から s の値を計算すればフラグを求めることができます*5 *6

#!/usr/bin/env sage

from ast import literal_eval


with open('output.txt', 'r') as f:
    output = f.read()
F, P = [loads(literal_eval(line.split(' = ')[-1])) for line in output.splitlines()]


v, m = 40, 14
for M, Q in zip(F, P):
    G = M.submatrix(0, 0, v, v)
    H = M.submatrix(0, v, v, m)
    R = Q.submatrix(0, v, v, m)
    h, r = H[:, 0], R[:, 0]
    try:
        s = (G + G.transpose()).solve_right(r - h)
    except ValueError:
        continue
    flag = bytes(i.to_integer() for i in s.list())
    if flag.startswith(b'CCTF{'):
        print(flag)
        break
CCTF{Un8reAk4Bl3_MQ-Sign_crYpT0_ma9iC!!}

Silky’s ‘noisy’ equations are like static on a radio—annoying, but solvable if you tune just right.

nc 91.107.252.0 31131

問題の概要

この問題では以下のファイルが配布されています。

  • 問題サーバで動かしているSageMathプログラム (Silky.sage)

この問題では、 B = 5, n = 19, D = 110, t = 128 がパラメーターとして使用されています。 最初に -B \le k _ i \le B を満たすランダムな整数を成分とする n 次元のベクトル k が生成されます。

この問題では問題サーバに接続して以下の操作をすることができます。

  • ベクトル R の生成
  • ベクトル k の値の入力

問題サーバでの操作は 11 回まで行うことができます。

ベクトル R の生成では、 -B D \le R _ i - k _ i \le B D を満たす満たすランダムな整数 R _ i を成分とする n 次元のベクトル R  \frac{t}{2} \left\lfloor \frac{4 D B}{t} \right\rfloor 個生成されます。 ベクトル k の値を入力したときに、正しい値であればフラグが表示されます。

 k は問題のプログラムではkeyに対応しています。

  • Silky.sage
#!/usr/bin/env sage

import sys
from Crypto.Util.number import *
from flag import flag

def die(*args):
    pr(*args)
    quit()
    
def pr(*args):
    s = " ".join(map(str, args))
    sys.stdout.write(s + "\n")
    sys.stdout.flush()
    
def sc():
    return sys.stdin.buffer.readline()

def randroad(B):
    return vector(ZZ,[randint(-B, B) for _ in range(n)])

def roadband():
    return randroad(B * (D + 1))

def silky(key):
    while True:
        R = roadband()
        _R = R - key
        if min(_R) >= - B * D and max(_R) <= B * D:
            return R

def main():
    border = "┃"
    pr(        "┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓")
    pr(border, ".:::      Welcome to the Silky cryptography oracle task!     :::.", border)
    pr(border, "Your mission is to find flag by analyzing this weird oracle! :-) ", border)
    pr(        "┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛")
    global flag, B, n, D, t
    B, n = 5, 19
    D, t = 110, 128
    l = int(4 * D * B / t)
    c, key = 0, randroad(B)
    while True:
        c += 1
        if c >= 12:
            die(border, "My brain is fried, quitting...")
        pr(f"{border} Options: \n{border}\t[G]et flag! \n{border}\t[M]ake Silky! \n{border}\t[Q]uit")
        ans = sc().decode().strip().lower()
        if ans == 'm':
            R = [silky(key) for _ in range(int(l * t // 2))]
            for i in range(len(R) // 16):
                pr(border, f"{str(R[16 * i:16 * (i + 1)]).replace(',', '')}")
        elif ans == 'g':
            pr(border, f'Please submit the secret key: ')
            inp = sc().decode().strip()
            try:
                _key = vector(ZZ, [int(_) for _ in inp.split(',')])
            except:
                die(border, f'The input you provided is not valid! Bye!!')
            if _key == key:
                die(border, f'Congrats! You got the flag: {flag}')
            else:
                die(border, f'Your key is incorrect!')
        elif ans == 'q':
            die(border, "Quitting...")
        else:
            die(border, "Bye...")

if __name__ == '__main__':
    main()
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃ .:::      Welcome to the Silky cryptography oracle task!     :::. ┃
┃ Your mission is to find flag by analyzing this weird oracle! :-)  ┃
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
┃ Options: 
┃       [G]et flag! 
┃       [M]ake Silky! 
┃       [Q]uit
g
┃ Please submit the secret key: 
-2,-2,-5,2,-4,-2,-1,-1,3,2,4,4,3,0,3,-1,4,4,-5
┃ Your key is incorrect!

解法

ベクトル R の成分 R _ i についての条件式を変形すると以下のようになります。

 \begin{align}
-B D &\le R _ i - k _ i \le B D \\
-B D + k _ i &\le R _ i \phantom{{} - k _ i} \le B D + k _ i
\end{align}

この式から R _ i の値が取る範囲が分かります。 この問題では生成される R の数が十分に多いので、 R _ i の最小値と最大値を計算すると -B D + k _ i, B D + k _ i が分かります。 そこで、以下の式を計算すれば k _ i の値が計算できます。

 \begin{align}
\frac{1}{2} \left( \left( -B D + k _ i \right) + \left( B D + k _ i \right) \right) &= \frac{1}{2} \cdot 2 k _ i  \\
&= k _ i
\end{align}

計算した k の値を問題サーバに入力すればフラグが得られます。

#!/usr/bin/env python3

from pwn import remote


# host = '91.107.132.34'
host = 'localhost'
port = 31131


def select_word(b, nl, nw):
    return b.splitlines()[nl].split(b' ')[nw]


with remote(host, port) as conn:
    conn.recvuntil(b'[Q]uit\n')
    R = []
    for _ in range(12 - 2):
        conn.sendline(b'M')
        data = conn.recvuntil(b'[Q]uit\n')
        R += [list(map(int, j.split(b' '))) for i in data.splitlines()[:-4] for j in i.strip('┃ [()]'.encode()).split(b') (')]
    
    k = [(max(i) + min(i)) // 2 for i in zip(*R)]
    print(f'{k = }')
    
    conn.sendline(b'G')
    conn.recvuntil(b'Please submit the secret key: \n')
    conn.sendline(', '.join(map(str, k)).encode())
    data = conn.recvall()
    flag = select_word(data, 0, -1).decode()
    print(flag)
$ ./solve.py
[+] Opening connection to localhost on port 31131: Done
k = [-5, 1, -4, 0, -3, 3, 2, -5, -5, 4, -5, 5, 3, -2, -4, -1, 0, 2, 4]
[+] Receiving all data: Done (81B)
[*] Closed connection to localhost port 31131
b'CCTF{k3Y_R3c0vEry_4TtaCk_On_A_l3AkY_5e4Si9n!}'
CCTF{k3Y_R3c0vEry_4TtaCk_On_A_l3AkY_5e4Si9n!}

Sticky situation: Toffee’s crypto seems sweet, until you’re stuck chewing on its unsolvable core.

nc 91.107.252.0 31111

問題の概要

この問題では以下のファイルが配布されています。

  • 問題サーバで動かしているSageMathプログラム (Toffee.sage)

この問題ではフラグを整数に直したものを秘密鍵 d としています。 また、楕円曲線 E  y^ 2 \equiv x^ 3 + a x + b \pmod p という式で定義され、 E 上の点 G = \left( x, y \right) が定義されています。  G の位数を n としています。  1 \le u \le n, 1 \le v \le n, 1 \le k \le n を満たすランダムな整数 u, v, k が生成されます。

この問題では問題サーバに接続して以下の操作をすることができます。

  • 入力したシード値に対する乱数の計算
  • 入力したメッセージに対する署名の計算

乱数の計算では、シード値 k を入力すると \left( u k + v \right) \bmod n という計算で乱数が生成されます。 署名の計算では、最初に k の値を使用して乱数が計算され、それを新しい値として k の値が置き換えられます。 それから、入力したメッセージ m に対する署名 r, s が以下の式で計算されます。

 \begin{align}
\left( x, y \right) &= k G \\
r &= x \bmod n \\
s &= k^ {-1} \left( H \! \left( m \right) + r d \right) \bmod n
\end{align}

ただし、 H はハッシュ関数でありこの問題ではSHA512が使用されています。

 d, n, m は問題のプログラムではskey, _n, msgに対応しています。

  • Toffee.sage
#!/usr/bin/env sage

import sys
from Crypto.Util.number import *
from hashlib import sha512
from flag import flag

def die(*args):
    pr(*args)
    quit()
    
def pr(*args):
    s = " ".join(map(str, args))
    sys.stdout.write(s + "\n")
    sys.stdout.flush()
    
def sc():
    return sys.stdin.buffer.readline()

def sign(msg, skey):
    global k
    h = bytes_to_long(sha512(msg).digest())
    k = toffee(u, v, k)
    P = k * G
    r = int(P.xy()[0]) % _n
    s = inverse(k, _n) * (h + r * skey) % _n
    return (r, s)

def toffee(u, v, k):
    return (u * k + v) % _n

def main():
    border = "┃"
    pr(        "┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓")
    pr(border, ".:::    Welcome to the Toffee chocolate cryptography task!    ::.", border)
    pr(border, ".:  Your mission is to find flag by analyzing the signatures!  :.", border)
    pr(        "┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛")
    global flag, u, v, k, _n, G
    skey = bytes_to_long(flag)
    p = 0xaeaf714c13bfbff63dd6c4f07dd366674ebe93f6ec6ea51ac8584d9982c41882ebea6f6e7b0e959d2c36ba5e27705daffacd9a49b39d5beedc74976b30a260c9
    a, b = -7, 0xd3f1356a42265cb4aec98a80b713fb724f44e747fe73d907bdc598557e0d96c5
    _n = 0xaeaf714c13bfbff63dd6c4f07dd366674ebe93f6ec6ea51ac8584d9982c41881d942f0dddae61b0641e2a2cf144534c42bf8a9c3cb7bdc2a4392fcb2cc01ef87
    x = 0xa0e29c8968e02582d98219ce07dd043270b27e06568cb309131701b3b61c5c374d0dda5ad341baa9d533c17c8a8227df3f7e613447f01e17abbc2645fe5465b0
    y = 0x5ee57d33874773dd18f22f9a81b615976a9687222c392801ed9ad96aa6ed364e973edda16c6a3b64760ca74390bb44088bf7156595f5b39bfee3c5cef31c45e1
    F = FiniteField(p)
    E = EllipticCurve(F, [a, b])
    G = E(x, y)
    u, v, k = [randint(1, _n) for _ in ';-)']
    while True:
        pr(f"{border} Options: \n{border}\t[G]et toffee! \n{border}\t[S]ign message! \n{border}\t[Q]uit")
        ans = sc().decode().strip().lower()
        if ans == 'g':
            pr(border, f'Please let me know your seed: ')
            _k = sc().decode().strip()
            try:
                _k = int(_k)
            except:
                die(border, 'Your seed is not valid! Bye!!')
            pr(f'{toffee(u, v, _k) = }')
        elif ans == 's':
            pr(border, f'Please send your message: ')
            msg = sc().strip()
            r, s = sign(msg, skey)
            pr(border, f'{r = }')
            pr(border, f'{s = }')
        elif ans == 'q':
            die(border, "Quitting...")
        else:
            die(border, "Bye...")

if __name__ == '__main__':
    main()
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃ .:::    Welcome to the Toffee chocolate cryptography task!    ::. ┃
┃ .:  Your mission is to find flag by analyzing the signatures!  :. ┃
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
┃ Options: 
┃       [G]et toffee! 
┃       [S]ign message! 
┃       [Q]uit
g
┃ Please let me know your seed: 
1349885082459563627012210356057999803266251039054960865564091492162360939641677539018037351205871696073328184546689140162372515915771517728111252758434268
toffee(u, v, _k) = 7275158793449321329012712780627349340032850673373118352342436144767182114969604995456991948366883716673088820603102742368126574526320813831235040917742184
┃ Options: 
┃       [G]et toffee! 
┃       [S]ign message! 
┃       [Q]uit
s
┃ Please send your message: 
test_msg
┃ r = 6291074798583990476086997793969242054123502459934188819855058594005961078653583096940666328496511987580307992176388323325494600764604130072507362884560064
┃ s = 9111758945473199454781231263790729006243995124326216035810377465913943567091319355518368631836426560164567803710764477953203790000687310742044642215249443
┃ Options: 
┃       [G]et toffee! 
┃       [S]ign message! 
┃       [Q]uit

解法

最初に乱数生成器のパラメータ u, v を求めます。 2つのシード値 k _ a, k _ b に対する乱数を t _ a, t _ b とすると、以下の式が成り立ちます。

 \begin{align}
t _ a &\equiv u k _ a + v \pmod n \\
t _ b &\equiv u k _ b + v \pmod n
\end{align}

この2つの式の差を計算すると以下のようになります。

 \begin{align}
t _ a - t _ b &\equiv \left( u k _ a + v \right) - \left( u k _ b + v \right) \\
t _ a - t _ b &\equiv u \left( k _ a - k _ b \right) \\
u &\equiv \left( t _ a - t _ b \right) \left( k _ a - k _ b \right)^ {-1} \pmod n
\end{align}

この式から u の値を計算できるので、 u の値を使用して以下のように v の値も求めることができます。

 \begin{align}
t _ a &\equiv u k _ a + v \\
v &\equiv t _ a - u k _ a \pmod n
\end{align}

 u, v の値が求められたので、次に秘密鍵 d の値の求め方を考えます。 2つのメッセージ m _ 1, m _ 2 を連続して署名したときの出力を \left( r _ 1, s _ 1 \right), \left( r _ 2, s _ 2 \right) とします。  z _ 1 = H \! \left( m _ 1 \right), z _ 2 = H \! \left( m _ 2 \right) とすると、以下の式が成り立ちます。

 \begin{align}
k _ 1 s _ 1 &\equiv z _ 1 + r _ 1 d \pmod n \\
k _ 2 s _ 2 &\equiv z _ 2 + r _ 2 d \pmod n
\end{align}

連続して計算した署名に使用された乱数を k _ 1, k _ 2 とすると、 k _ 2 \equiv u k _1 + v \pmod n が成り立っています。 また、 k _ 1 についての式を得るために k _ 1 s _ 1 \equiv z _ 1 + r _ 1 d \pmod n を変形すると、 k _ 1 \equiv \left( z _ 1 + r _ 1 d \right) s _ 1^ {-1} \pmod n となります。  k _ 1, k _ 2 についての式を s _ 2 \equiv k _ 2^ {-1} \left( z _ 2 + r _ 2 d \right) \pmod n に代入して d について解くと以下のようになります。

 \begin{align}
k _ 2 s _ 2 &\equiv z _ 2 + r _ 2 d \\
\left( u k _1 + v \right) s _ 2 &\equiv z _ 2 + r _ 2 d \\
\left( u \left( \left( z _ 1 + r _ 1 d \right) s _ 1^ {-1} \right) + v \right) s _ 2 &\equiv z _ 2 + r _ 2 d \\
u \left( z _ 1 + r _ 1 d \right) s _ 1^ {-1} s _ 2 + v s _ 2 &\equiv z _ 2 + r _ 2 d \\
u \left( z _ 1 + r _ 1 d \right) s _ 2 + v s _ 1 s _ 2 &\equiv z _ 2 s _ 1 + r _ 2 s _ 1 d \\
u z _ 1 s _ 2 + u r _ 1 s _ 2 d + v s _ 1 s _ 2 &\equiv z _ 2 s _ 1 + r _ 2 s _ 1 d \\
u r _ 1 s _ 2 d - r _ 2 s _ 1 d &\equiv z _ 2 s _ 1 - u z _ 1 s _ 2 - v s _ 1 s _ 2 \\
\left( u r _ 1 s _ 2 - r _ 2 s _ 1 \right) d &\equiv z _ 2 s _ 1 - u z _ 1 s _ 2 - v s _ 1 s _ 2 \\
d &\equiv \left( z _ 2 s _ 1 - u z _ 1 s _ 2 - v s _ 1 s _ 2 \right) \left( u r _ 1 s _ 2 - r _ 2 s _ 1 \right)^ {-1} \pmod n
\end{align}

この式から秘密鍵 d が求まるので、それをバイト列に直せばフラグが得られます。

#!/usr/bin/env python3

from pwn import remote
from Crypto.Util.number import inverse, bytes_to_long, long_to_bytes
import hashlib


# host = '91.107.133.165'
host = 'localhost'
port = 31111


def select_word(b, nl, nw):
    return b.splitlines()[nl].split(b' ')[nw]


n = 0xaeaf714c13bfbff63dd6c4f07dd366674ebe93f6ec6ea51ac8584d9982c41881d942f0dddae61b0641e2a2cf144534c42bf8a9c3cb7bdc2a4392fcb2cc01ef87

with remote(host, port) as conn:
    conn.recvuntil(b'[Q]uit\n')
    
    k_list = [0, 1]
    t_list = []
    for k in k_list:
        conn.sendline(b'G')
        conn.recvuntil(b'Please let me know your seed: \n')
        conn.sendline(str(k).encode())
        data = conn.recvuntil(b'[Q]uit\n')
        t = int(select_word(data, 0, -1))
        t_list.append(t)
        print(f'{t = }')
    
    k_a, k_b = k_list
    t_a, t_b = t_list
    u = (t_a - t_b) * inverse(k_a - k_b, n) % n
    v = (t_a - u * k_a) % n
    
    msg_list = [b'message 1', b'message 2']
    sign_list = []
    for msg in msg_list:
        conn.sendline(b'S')
        conn.recvuntil(b'Please send your message: \n')
        conn.sendline(msg)
        data = conn.recvuntil(b'[Q]uit\n')
        r = int(select_word(data, 0, -1))
        s = int(select_word(data, 1, -1))
        sign_list.append((r, s))
        print(f'{r = }')
        print(f'{s = }')

z1, z2 = [bytes_to_long(hashlib.sha512(msg).digest()) for msg in msg_list]
(r1, s1), (r2, s2) = sign_list
d = (z2 * s1 - u * z1 * s2 - v * s1 * s2) * inverse(u * r1 * s2 - r2 * s1, n) % n

flag = long_to_bytes(d)
print(flag)
$ cp ./solve.py
[+] Opening connection to localhost on port 31111: Done
t = 4025427050577291061949661643475998536831099574286970618690251096897065760240730158490312683218966481395825755716155427446530945902787797847963626310270244
t = 1935582350085531490972208569075672627487273067839400707161421928902298170041727091698642128089704726232934072718353161553502876746169413602916561905318307
r = 4401108489900533004946015305916616646271638705395439173540276868562255084844339283797840156995291934593020591528025367929330595978606082984337073415470060
s = 8471965983288186464863532198905236714380320758863998608877973692077173209964535892437249260349642495732775883204399263601255169520363554006285962527328618
r = 4667585313947543715262021217920223198681074987046977978519149711761455138562524538793552252524128218094685189257488572695714079162205908406593718248076090
s = 7288856689060883203470993879319337623147520289782134560853035911617945898289899710801265912501160621211395955361925987255434612073577908160345707158236619
[*] Closed connection to localhost port 31111
b'CCTF{4fFin3Ly_r3lA7eD_n0nCE5_aR3_!n5eCuR3!}'
CCTF{4fFin3Ly_r3lA7eD_n0nCE5_aR3_!n5eCuR3!}

*1: 過去に公開した記事についても同様です。

*2: 結果的にx座標の重複はなかったので、この考えで正しく問題を解くことが出来ました。

*3: ここまでの手順で逆元が求まらず計算できなかった場合は、再度接続して別の値で計算し直します。

*4: 連立方程式の解は複数存在しますが、m_0, m_1, m_2, m_3, m_4, m_5は2^8l未満であるので、その条件を満たすものを取り出したら一意に定まり、m_0, m_1, m_2の値が分かりました。

*5: 複数個の出力結果があるので、sの値が一意に定まらない場合は他の出力結果を使用して計算すれば良いです。

*6: 問題を解く際に手元のSageMathではバージョンの差異によってloads関数で正しくデータを読み込むことができなかったので、SageMathCellやCoCalcを使用して問題を解きました。