jarno raid tarkvara sogastamineraid/obfuscate.pdf · 2005. 6. 7. · 2.1.2 piraatluse negatiivne...
TRANSCRIPT
T A R T U Ü L I K O O L
MATEMAATIKA-INFORMAATIKATEADUSKOND
Arvutiteaduse instituut
Krüptograafia õppetool
Informaatika eriala
Jarno Raid
Tarkvara sogastamineBakalaureusetöö
Juhendaja: prof. A. Buldas
Autor: ........................................... “.....” mai 2005
Juhendaja: .................................... “.....” mai 2005
Õppetooli juhataja: ...................... “.....” mai 2005
TARTU 2005
Sisukord
1 Sissejuhatus 4
2 Probleemi olemus 7
2.1 Arvutitarkvara ja piraatlus . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
2.1.1 Tarkvarapiraatluse vormid . . . . . . . . . . . . . . . . . . . . . . . . 8
2.1.2 Piraatluse negatiivne mõju . . . . . . . . . . . . . . . . . . . . . . . . 10
2.1.3 Tarkvara kaitsmise põhjuseid . . . . . . . . . . . . . . . . . . . . . . . 11
2.2 Seadusandlikud meetmed . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
2.3 Tehnoloogilised meetmed . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
2.3.1 Riistvaralised meetmed . . . . . . . . . . . . . . . . . . . . . . . . . . 14
2.3.2 Tarkvaralised meetmed . . . . . . . . . . . . . . . . . . . . . . . . . . 16
3 Ülevaade sogastamisest 22
3.1 Sogastamise olemus ja kasutusvaldkond . . . . . . . . . . . . . . . . . . . . . 22
3.2 Sogastamise käsitletus kirjanduses . . . . . . . . . . . . . . . . . . . . . . . . 23
3.3 Sogastamise võimatus . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
4 Sogastaja võimatuse formaalne tõestus 27
4.1 Tähistused . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
4.2 Sogastaja . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
4.3 Sogastaja võimatus . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32
4.4 Kahe TM sogastamine . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33
4.5 Ühe TM sogastamine . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38
4.6 Sogastamatute funktsioonide pere . . . . . . . . . . . . . . . . . . . . . . . . 41
4.7 Tulemuse tähendus . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44
4.8 Tulemuse laiendused . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46
5 Praktiline lähenemine 48
5.1 Sogastamistehnikate liigitus . . . . . . . . . . . . . . . . . . . . . . . . . . . 49
5.1.1 Vorminguline sogastamine . . . . . . . . . . . . . . . . . . . . . . . . 49
5.1.2 Käsuvoo sogastamine . . . . . . . . . . . . . . . . . . . . . . . . . . . 50
5.1.3 Andmesogastamine . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57
2
5.1.4 Lisavõimalused . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61
5.2 Sogastamise vastaseid ründeid . . . . . . . . . . . . . . . . . . . . . . . . . . 62
5.3 Sogastamise efektiivsus . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63
5.4 Sogastamise alternatiive . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65
6 Sogastamise käsitlus peale võimatuse tõestust 67
7 Edasised arengusuunad 70
8 Summary 71
9 Kasutatud kirjandus 73
3
1 Sissejuhatus
Meie elus igapäevaselt kasutatava tarkvara rolli suurenemisega kaasneb üha suurenev vajadus
tõhusa intellektuaalse omandi1 kaitse järele. Intellektuaalse omandi kaitsmine on olulise täht-
susega, kuna selle kuritarvitamise mõjud ulatuvad palju kaugemale tarkvaratööstuse piiridest.
Seejuures on probleemil kaks teineteisest selgesti eristatavat külge. Ühelt poolt on tarkvarakait-
se ülesandeks levitatava programmi lõppkasutaja poolse väärkasutuse vastane kindlustamine
(tegemist on järjest enam silmapaistva ja käsitletava probleemiga, mille tõttu jääb ülemaailmsel
tarkvaratööstusel iga-aastaselt saamata kümneid miljardeid dollareid). Raskemini hinnatavad
on aga kahjud, mis kaasnevad konkurentide poolse tarkvara kuritarvitusega – tootes kasutatud
ideede varastamisega.
Mõlemad on olulised probleemid ning olenevalt sellest, mille või kelle eest tarkvara soo-
vitakse kaitsta, sõltub kasutatavate meetmete valik. Erinevaid kaitsemeetmeid on palju ning
neid võib liigitada mitmeti. Kõige üldisemaks jaotusviisiks oleks kaitsemeetmete liigitamine
seadusandlikeks ja tehnilisteks. Kuigi seadusandlikel meetoditel on ka omad head küljed, on
nende kõigi ühiseks suureks puuduseks see, et nad ei tegele mitte põhjuste, vaid tagajärjedega
võitlemisega. Seda nõrkust ei ole tarkvarakaitse tehnilistel vahenditel, mis omakorda jagunevad
riistvaralisteks ja tarkvaralisteks meetmeteks. Kuigi ka riistvaralistel meetmetel on omi eeli-
seid, seab nende levikule piirid eriotstarbeliste seadmete või andmekandjate vajalikkus, mis
teeb tarkvara kliendile toimetamise soovimatult tülikaks. Seadusandlike ja riistvaraliste meet-
mete suurimatest puudustest on vabad tarkvaralised intellektuaalse omandi kaitsevahendid.
Erinevaid tarkvaralisi intellektuaalse omandi kaitsemeetodeid on mitmeid, millest üks vii-
mastel aastatel enim populaarsust kogunud meetmeid on sogastamine. Sogastamise vajalikkust
ja populaarsust selgitatakse sageli endas palju metainfot kandvate ning sellest tulenevalt kerges-
ti dekompileeritavate ja pöördprojekteeritavate programmeerimiskeelte (eriti java) esiletõusuga.
Samuti aitab tarkvaraliste meetmetete ning seal hulgas sogastamise kiirele arengule kaasa pro-
1Intellektuaalne omand (intellectual property) on mis tahes vaimse tegevuse või idee väljendusvorm. Selle
neljaks põhitüübiks on üpris erinevalt käituvad patent, autoriõigus, kaubamärk ning disain. Arvutiprogramm või
selle elemendid võivad kuuluda neist igaühe alla. Käesolevas töös on intellektuaalse omandi all silmas peetud
arvutiprogrammi ning selles kasutatud algoritme, disainielemente jms.
4
grammide levitamiskiiruse kriitilisus.
Sogastamise all mõistetakse mingite kindlate semantikat säilitavate teisenduste abil prog-
rammikoodi võimalikult arusaamatuks muutmist. Teisenduste abil püütakse varjata andmeväl-
jade otstarvet, käsuvoo tegelikku käitumist, muuta koodi vormingut jne. Kuna paljude sogas-
tamisteisendustega kaasnevad teatavad lisakulutused ressurssidele, tuleb kõiki neid läbi viies
silmas pidada, et programm ei kaotaks oluliselt oma jõudluses. Sogastamist ei kammitse riist-
varaliste meetmete puudused ning ta on reaalselt ründeid ennetav kaitsemeede, millel on üks
kindel eesmärk – takistada pöördprojekteerimist. Tegemist on kaitsemeetmega, millel puudu-
vad samaväärsed alternatiivid.
Esimesed põhjalikud ja tõsiseltvõetavad sogastamise olemust, erinevaid tehnikaid ja nende
efektiivsust käsitlevad publikatsioonid pärinevad eelmise sajandi 90ndate aastate teisest poolest.
Sellest ajast saadik on välja pakutud suhteliselt erinevatest vaatevinklitest sogastamisele lähene-
vaid praktilisi meetodeid ning loodud äriotstarbelisi ja vabavaralisi sogastajaid. Kuigi see teema
huvitab paljusid ja pakutakse välja järjest uusi heuristilisi sogastamistehnikaid, on sogastamise
teaduslikud alused peaaegu välja töötamata ning võib öelda, et tegemist on alles tekkejärgus
alaga.
Käesoleva töö eesmärk on anda ülevaade sogastamise teoreetilistest alustest ja selle prak-
tilistest võtetest.
2001. aastal tõestas grupp matemaatikuid ja krüptolooge, et standardse musta kasti defi-
nitsioonist lähtuvat sogastajat ei eksisteeri – st ei leidu sogastajat, mille abil oleks võimalik
suvaline programm muuta nö virtuaalseks mustaks kastiks. Sogastatud programmi O(P ) mus-
ta kasti omadus on definteeritud järgnevalt – kõik, mis on arvutatav sogastatud programmist
O(P ), peab olema efektiivselt arvutatav ka P -oraaklipääsuga. Näitamaks, et sellist turvalisust
pakkuv sogastaja ei ole praktiliselt teostatav, on käesoleva töö 4. peatükis refereeritud tõestus,
et leidub sogastamatute funktsioonide pere. Sellesse peresse kuuluvate funktsioonide puhul on
kergesti arvutatav mingi omadus π(f), omades juurdepääsu seda funktsiooni arvutavale Boo-
le’i skeemile (programmile), kuid programmi sisend/väljund käitumist uurides π(f) väärtuse
5
leidmise tõenäosus ei ole parem juhuslikust arvamisest. See tähendab, et neid funktsioone sisal-
davate programmide puhul ei ole musta kasti definitsioonist lähtuv turvalisus saavutatav ühegi
sogastaja abil.
Võimatuse tõestus ei tähenda aga sugugi, et sogastamine praktikas võimatu oleks. Siinkohal
võib tõmmata ajaloolise paralleeli 1960ndatel aastatel tõestatud Rice’i teoreemiga, millega näi-
dati, et programne semantika uurimine on võimatu. Sellest hoolimata tegeletakse programmide
semantika uurimisega tänapäeval edukalt. Samuti ei saa ainuüksi sogastamatute funktsioonide
pere leidumise tõttu sogastamist tarkvarakaitsel kasutuks tunnistada. Nii enne ideealse sogasta-
mise võimatuse tõestust kui ka peale seda on tehtud selles valdkonnas palju praktilist tööd ning
erinevatest sogastamistehnikatest ning nende liigitusest annab ülevaate 5. peatükk. Vaatamata
nö negatiivsetele tulemustele sogastamise turvalisuse seisukohast, tehakse tööd antud teemal
edasi ning avaldatakse sogastamise teemalisi heuristilisi ja vähem heuristilisi artikleid.
Käesolev töö on referatiivne ning selle eesmärk on esialgse, kuid põhjaliku ülevaate andmi-
ne neile (tudengitele, kraadiõppuritele), kes soovivad antud teemaga süvitsi minnes tegeleda.
6
2 Probleemi olemus
2.1 Arvutitarkvara ja piraatlus
Autoriõigustega on kaitstud kõikvõimalikud teosed paljudest erinevatest eluvaldkondadest. Ees-
ti Vabariigis kehtiva “Autoriõiguse seaduse” [1] §4 lg 3 p 3 järgi kuuluvad arvutiprogrammid
autorikaitse alla sarnaselt kirjandusteostele – st programme käsitletakse kui kirjatükke. Kaitse
laieneb arvutiprogrammi mis tahes väljendusvormile ning kehtib ka programmi loomise lähte-
materjalidele. Kuigi arvutitarkvara lahutamatuks osaks loetakse ka kasutusjuhendid, tarkvara-
kirjeldused jne, on kõige tähtsamaks – samuti siin ja edaspidi kõne all olevaks – osaks arvuti-
programm.
Tarkvara litsentseerimisel annab programmi looja kliendile tarkvara kasutamiseks litsentsi-
lepingus sätestatud tingimustel. Lepingu tingimused on autori määratavad, kuid on mõningal
määral piiratud kehtiva “Autoriõiguse seadusega”. Näiteks ei ole “Autoriõiguse seaduse” §18
lg 2 p 4 järgi lubatud arvutiprogramme reprodutseerida isiklikeks vajadusteks ilma autori nõus-
olekuta ja autoritasu maksmiseta, kuid sama seaduse §24 kohaselt on see erandkorras lubatud
programmis olevate vigade parandamiseks, programmi kasutamiseks seadmetel, ulatuses ja ees-
märkidel, milleks programm omandati ning lubatud on ka varukoopia tegemine hävinud, kadu-
nud või kasutuskõlbmatuks muutunud programmi taastamiseks. Samuti on lubatud §25 alusel
dekompileerimine, kui see on hädavajalik informatsiooni saamiseks algsest programmist sõl-
tumatult loodud programmi ühilduvuse tagamiseks teiste programmidega. Dekompileerimise
võimalikkus soodustab aga konkurentide poolset koodivargust.
Tarkvara ostes (või ka tasuta saades) ei ole, lähtuvalt “Autoriõiguse seadusest” oluline, kas
tarkvara omandati edasimüüjalt või otse selle loojalt, kasutades andmekandjana CD-d, disket-
ti, Internetti või muud kanalit, kuna erinevalt tavalisest ostu-müügi tehingust ei omanda ostja
programmi, vaid saab selle kasutusõiguse just selliste piirangute ja õigustega, nagu seda näeb
ette litsentsileping. Programm ise jääb oma autori omandiks, kasutaja nõustub autori esitatud
tingimustega ning on vastutav, kui rikutakse lepingu tingimusi.
Piraatkoopiaks loetakse arvutiprogrammi mis tahes riigis reprodutseeritud koopiat, kui se-
7
da on tehtud ilma autori või autoriõiguste omaja loata. Samuti loetakse piraatkoopiaks sellist
koopiat, mis on reprodutseeritud välisriigis autoriõiguste omaja loal, kuid mida levitatakse või
kavatsetakse levitada Eestis ilma autoriõiguste omaja loata. “Autoriõiguse seaduse” §82 koha-
selt loetakse piraatkoopiaga kauplemiseks piraatkoopia müüki, rentimist, müügile pakkumist
või rendile pakkumist, samuti piraatkoopia ladustamist, hoidmist või edasitoimetamist ärilisel
eesmärgil.
2.1.1 Tarkvarapiraatluse vormid
Tarkvarapiraatlusel on mitmeid erinevaid vorme ning see, kuidas neid liigitada ja milliseid neist
välja tuua, on mõneti meelevaldne.
Üks võimalik jaotus on järgmine:
• Tarkvara võltsimine (counterfeiting);
• Litsentsita tarkvara installeerimine (hard-disk loading);
• Piraatkoopiate levitamine Internetis ja allalaadimine Internetist (Internet piracy);
• Tarkvara reprodutseerimine (end-user copying);
• Rentimine või laenutamine (renting or leasing).
Tarkvara võltsimine on illegaalne ning enamasti suuremahuline autorikaitse alla kuuluva
tarkvara reprodutseerimine ja levitamine (müük). Erinevalt tavalisest piraatkoopiast näeb võlt-
sing tihti välja autentne – reeglina kuulub sinna juurde originaali täpselt matkiv pakend, aga
võimalik, et lisaks on veel ka kasutusjuhend, libalitsentsid ja isegi originaalile sarnanevad tur-
vaelemendid. Seetõttu võib osutuda originaali ning piraatkoopia vahel vahet tegemine üsnagi
raskeks. See omakorda võimaldab võltsingut müüa originaalilähedase hinnaga ning saada suu-
remat kasumit. Tarkvara võltsimine rikub autori varalisi õigusi, kaubamärgi omaniku õigusi
ning selle kasutamine on käsitletav seaduserikkumisena, kuna puudub autori luba (litsents) too-
det kasutada.
8
Litsentsita tarkvara installeerimise ehk hard-disk loadingu all peetakse silmas illegaalse
tarkvara paigaldamist arvuti kõvakettale. Sellisel juhul puuduvad dokumendid, mis tõestaksid
inimese õigust kasutada antud tarkvara ning samuti ei ole tarkvara kasutajal originaalandme-
kandjaid (CD-d, disketid) ja muid komponente, mis sama tarkvara legaalse vormiga alati kaasas
käivad. Selline teguviis on levinud esmajoones väiksemate (ja vähemtuntud) arvutifirmade seas,
kes üritavad müüdavat riistvara lisatava (litsentsita) tarkvara abil atraktiivsemaks muuta.
Piraatkoopiate levitamine Internetis ja allalaadimine Internetist (nimetagem seda inglise-
keelse vaste (Internet piracy) eeskujul edaspidi Internetipiraatluseks) on tarkvarapiraatluse üks
nooremaid vorme. Sellest hoolimata on tegemist piraatluse vormiga, mis tarkvara tootjatele
(ning laiemalt võttes kõigile, kes oma autoriõigusi kaitsta soovivad) vast kõige enam peavalu
valmistab. Internetipiraatlusele aitavad kaasa Interneti kasutajate arvu plahvatuslik kasv, suhte-
liselt väike vahelejäämise risk, suurenevad andme-edastuse kiirused jms. Enimtuntud vahendid,
mille kaudu piraattarkvara Internetis liigub, on ftp-serverid, failivahetusprogrammid ning tava-
lised veebiserverid.
Tarkvara reprodutseerimine on reeglina ebaseaduslik (välja arvatud punktis 2.1 toodud erand-
juhud) ning selle võib jagada tinglikult kaheks:
• Reprodutseerimine otsese tulu saamise eesmärgita;
• Reprodutseerimine otsese tulu saamise eesmärgil.
Esimesse kategooriasse langevad juhud, kus arvutisse on installeeritud reprodutseeritud
tarkvara ilma sellekohase litsentsi ja autoriõiguste omaja loata või on tarkvara paigaldatud roh-
kematesse arvutitesse, kui seda lubab omandatud litsents (kasutatakse inglise keelset terminit
softlifting). Siia alla kuulub ka teine litsentsi ületarvitamise võimalus – tarkvara installeeritakse
kesksesse serverisse ning see on kasutamiseks kättesaadav klientarvutites, kuid kasutajaid on
litsentsiga lubatust rohkem (client-server overuse). Ka sõbrale laenamise või töölt koduarvutis-
se tehtud koopia korral võib rääkida ebaseaduslikust tarkvara reprodutseerimisest. Tegemist on
maailmas enim levinud tarkvarapiraatluse vormiga, mis moodustab rahaliselt mõõtes enam kui
poole piraatluse tõttu saamatajäänud tuludest.
9
Ebaseadusliku reprodutseerimise teise kategooria moodustavad juhtumid, mida ei saa klas-
sifitseerida võltsinguks, kuna isegi ei püüta kopeeritud isendist jätta muljet kui originaalist, ent
sarnaselt võltsingule on tarkvara kopeeritud tulusaamise eesmärgil ehk müügiks. Sellised pi-
raatkoopiad on enamasti kordades või isegi suurusjärgu võrra odavamad originaalist.
Selleks, et autoriõigusi kurjasti ära kasutada, ei pruugi tarkvara olla illegaalse päritoluga,
vaid ka täiesti seaduslikult soetatud tarkvara laenamine või rentimine võib olla vastuolus lit-
sentsilepinguga ning on sellest johtuvalt karistatav tegevus. “Autorikaitse seaduse” järgi võib
õiguste omanik laenamist või rentimist lubada (AutÕS §13 p 2 [1]), kuid ta ei pruugi seda su-
gugi teha. Siinjuures on oluline kahel mõistel vahet teha – kui rentimine on tarkvara või selle
koopia andmine ajutiseks kasutamiseks otsese või kaudse tulu saamise eesmärgil, siis laenuta-
mise puhul mingit tulu saamise eesmärki kaasatud ei ole.
2.1.2 Piraatluse negatiivne mõju
BSA (Business Software Alliance) ning IDC (International Data Corporation) viisid 2004. aas-
tal läbi ülemaailmse uurimuse illegaalse piraattarkvara kasutusest 2003. aastal [3]. Uuringu
tulemusena ilmnes, et keskeltläbi 36% kogu maailmas arvutitesse installeeritud äritarkvarast oli
illegaalse päritoluga. 2003. aastal paigaldati personaalarvutitesse äritarkvara hinnanguliselt 80
miljardi dollari väärtuses, millest, nagu juba mainitud, rohkem kui kolmandiku moodustas pi-
raattarkvara. See tähendab umbes 29 miljardi USA dollari suurust saamata jäänud tulu.
Kõige suurema piraattarkvara osakaaluga regiooniks oli 2003. aastal jätkuvalt Ida-
Euroopa (71%) ning kõige väiksema osakaaluga USA ning Kanada 23%. Samas on Ida-Euroo-
past poole väiksema piraattarkvara osakaaluga Lääne-Euroopas tekitatud rahaline kahju regioo-
niti suurim – 9,6 miljardit. Lähis-Ida ja Aafrika riigid, kus piraattarkvara osakaal riigiti üle 80
ja 90% küündib, toodavad aga ligi 7 korda väiksemat kahju kui USA ja Kanada. Eestis arva-
takse olevat ebaseaduslikku tarkvara 54 protsendi ulatuses, mis rahaliselt väljendub 14 miljonis
saamatajäänud dollaris.
Ühest küljest on levinud arvamus, et see kahju on hüpoteetiline ning puudutab vaid nii-
gi hästitoimivaid tarkvaraarendajaid. Teisalt on aga selge, et tarkvarapiraatlus põhjustab tõsist
10
kahju kogu ühiskonnale, mis avaldub loomatajäänud töökohtades, sellest tulenevas palkade ja
maksude saamata jäämises, tarkvaratööstuse arenemise kiiruse pidurdamises ning võimalikes
investeeringute tegemata jätmises. Samuti kannatab viljakaks piraatluse kasvulavaks oleva riigi
maine nagu ka kultuuri ja hariduse edendamine.
2.1.3 Tarkvara kaitsmise põhjuseid
Kõige peamisemaks intellektuaalse omandi kaitsmise põhjuseks on loomulikult soov tehtud ku-
lutused ressurssidele tagasi teenida. Piraatlus tõkestab autorit saamast väärilist tasu tehtud töö
eest. Kesiste või olematute kaitsemeetmete puhul suureneb risk ja ahvatlus võimalusi kurjasti
ära kasutada.
Programmi binaarkoodi dekompileerides ning lähtekoodi uurides võib konkureeriv arendaja
varastada ideid ja algoritme samalaadse toote loomiseks ning selle abil hulgaliselt omi ressurs-
se kokku hoida. Seda on väga raske välistada, avastada või keelata, kui tarkvara ei ole õigete
vahendite abil kaitstud, ning varguse tõestamine võib osutuda võimatuks. See pärsib õiglast
konkurentsi ning kannatab tegelik autor.
Sageli on kokkuvõttes odavam kulutada aega ja raha kaitsemehhanismide väljatöötamise-
le ja rakendamisele, kuna üldjuhul kaotatakse piraatlusele oluliselt suuremaid summasid. Mida
raskemini on kättesaadav töötav piraatversioon, seda suurem on tõenäosus, et ostetakse origi-
naal ning suurenevad saadavad tulud. Kuigi iga süsteem on lahtimurtav, ei tähenda see, et kait-
semehhanismide loomise peale tehtavad kulutused kasutud oleks. Tuum peitub selles, et kaitse
lahtimurdmine tuleb teha nii raskeks, et see osutuks – olenevalt eesmärgist – mõttetumaks pro-
grammi ostmisest või selle ise nullist loomisest.
Tarkvara kaitsmiseks on olemas palju erinevaid meetmeid. Sõltuvalt kaitstavast objektist
ning taotletavast eesmärgist tuleb valida õige meede või meetmete komplekt, et tagada maksi-
maalne võimalik turvalisus. Järgnevalt on toodud ülevaade erinevatest tarkvarakaitse meetme-
test.
11
2.2 Seadusandlikud meetmed
Autoriõigus
“Autoriõiguse seaduse” [1] kohaselt tekib arvutiprogrammidele ning nende mis tahes väljen-
dusvormidele automaatselt autoriõigus, kuid seaduse viienda paragrahvi 8nda punkti kohaselt
ei kaitsta ideid ning põhimõtteid, millele rajanevad programmi elemendid. Seega ei ole “Auto-
riõiguse seaduse” järgi kaitstav idee iseenesest, küll on aga kaitstud selle idee väljendusvorm –
programmikood.
Kuna enamasti ei ole kommertstarkvara loojate huvides, et nende ideid ning algoritme kon-
kurendid kerge vaevaga ära saaksid kasutada, jääb siin “Autoriõiguse seaduse” poolt pakuta-
vast kaitsest väheks, kuna see käsitleb peamiselt vaid loata tarkvara kopeerimist ning sellele
järgnevat kuritarvitamist. Samuti püsib koodifragmentide kopeerimise seaduslikkuse küsimus.
Seetõttu ei piisa tarkvarakaitseks kindlasti mitte ainult kõnealusest seadusest.
Patendiõigus
Sarnaselt autoriõigusele ei kaitse ka patendiõigus ideed, vaid leiutist e. mingi probleemi uudset
lahendust. “Patendiseaduse” [2] §6 lg 2 p 5 järgi ei loeta leiutise objektiks muu hulgas arvuti-
algoritme ja -programme ning seega ei saa ka neid otseselt patenteerida, kuid seda on võimalik
teha, kui programm on seotud mingi leiutise objektiga. Kuigi tarkvarale patendi taotlemine
võib võtta rohkem aega, kui on toote enda eluiga ning lisaks sellele on protsess ka kulukas, se-
da vahelduva eduga ikkagi kasutatakse (eriti USA-s). Patendiõiguse rakendamise kasuks räägib
asjaolu, et võrreldes autoriõigusega antakse pantendi omajale laiemad õigused: kui autorikait-
se rikkumiseks ei loeta identse teose loomist iseseisvalt, siis sama lahenduse väljatöötamine
iseseisvalt teise isiku poolt loetakse patendiõiguse rikkumiseks.
Ärisaladuse õigus
Ärisaladuse õigus võimaldab keelata teistel isikutel kasutada või avalikustada toote kohta käivat
salajast informatsiooni, kui see on vastuolus pooltevahelise lepinguga. Ärisaladuse valdajal ei
ole õigust takistada ärisaladuse objektiks oleva teabega identse teabe väljatöötamist, kuid üheks
ärisaladuse tunnuseks loetakse, et kaitstavat teavet peab olema võimatu legaalsete vahendite abil
12
reprodutseerida. Ärisaladuse õigusega võib olla kaitstud erinevalt autorikaitse õigusest tarkva-
ra mõni funktsioon, idee, algoritm vms, mis annab tarkvarakaitsele uued mõõtmed ning seda
kasutatakse üsna laialdaselt.
Lepinguõigus
Tarkvara litsentsilepingul on kaks peamist eesmärki:
• Määrata kindlaks tarkvara kasutamise tingimused;
• Tagada lepingutingimuste rikkuja vastutusele võtmise võimalus.
Tavaliselt keelatakse litsentsilepinguga tarkvara reprodutseerimine, selle levitamine, muut-
mine, dekompileerimine ja muud tegevused, mis mingil viisil võivad seada ohtu toote autori
või autoriõiguste omaja huvid. Tihti on litsentsilepinguga määratud ka tarkvaraga kaasas ole-
va dokumentatsiooni ning kasutusjuhendite kasutustingimused. Litsentsilepingu ning tehniliste
meetmete koosrakendamisega võidakse sundida kasutajat loobuma “Autoriõiguse seadusega”
tagatud õigustest. Näiteks võib olla kasutaja sunnitud litsentsilepinguga nõustudes aktsepteeri-
ma tarkvara tootja poolt tehniliste vahenditega tarkvarast koopia tegemise võimatuks muutmist,
kuigi “Autoriõiguse seadus” lubab erijuhtudel tarkvarast koopiaid teha.
Seadusandlike meetmete tõhusus
Eelpool loetletud seadusandlike meetmete tõhusus sõltub ennekõike riigi õigussüsteemist ning
konkreetse kaitstava objekti iseärasustest. Kõigi nende ühiseks puuduseks on aga see, et kokku-
võttes ei hoita mis tahes seadusandliku meetme või nende komplekti rakendamisel midagi ära,
vaid luuakse ainult baas, mille alusel võimalikke rikkumisi klassifitseerida. Ükski seadus ega
leping ei anna kaitset rünnete eest, vaid annab võimaluse võidelda tagajärgedega. See on aga
reeglina keeruline ja aeganõudev protsess.
2.3 Tehnoloogilised meetmed
Kuna seadusandlikud meetmed annavad meile parimal juhul vahendid võitlemaks tagajärgede-
ga, kuid ei hoia ära ründeid, on efektiivseks tarkvara kuritarvitamise vastaseks kaitseks vaja
rakendada ka tehnoloogilisi meetmeid. Tehnoloogilised meetmed, mille abil püütakse tagada,
13
et toodetud tarkvarast ei tehtaks piraatkoopiaid, et neid ei dekompileeritaks, muudetaks jne,
jagatakse esmalt kahte suurde klassi – tarkvaral ja riistvaral põhinevad vahendid.
2.3.1 Riistvaralised meetmed
Erinevalt seadusandlikest vahenditest pakuvad riistvaralised vahendid reaalset, ennetavat rünne-
tevastast kaitset. Enamasti on riistvaralised meetmed suunatud tarkvara illegaalse kopeerimise
vastu, st püütakse vältida tarkvara kopeerimist ja litsentseerimata kasutamist, kuid muud tark-
varakaitse vaatevinklist olulised aspektid on katmata. Ilma riistvaralise kaitse abita on mis tahes
programm (kui tahes krüpteeritud, sogastatud vms) oma olemuselt lihtsalt bitijada, mida on või-
malik alati kopeerida, oma masinal käivitada ja uurida.
Peamised riistvaralised tarkvara kaitsmise meetmed on järgnevad:
• Kaitstud protsessor (shielded CPU) ja krüpteeritud andmed;
• Limiteeritud installeerimised;
• Pordilukk (dongle);
• Kaitstud andmekandja;
• Peidetud seerianumbrid;
• CD-key.
Parima võimaliku kaitse tarkvarale annaks füüsiliselt kaitstud eriotstarbeliste arvutite (nt
mängukonsoolid) müümine koos vastava tarkvaraga, kuid praeguseid tehnoloogilisi võimalu-
si ning üldotstarbelistele arvutitele suunatud tootmist arvestades on see praktiliselt välistatud.
Hoopis reaalsem on kasutada täielikult eriotstarbelise süsteemi asemel nö tarkvara-riistvara-
paketti (SH-packet ehk software-hardware-packet [4]), mis koosneb kaitstud protsessorist ning
krüpteeritud tarkvarast. Sellise lahenduse puhul on protsessori eriotstarbelisse ROM mällu tal-
letatud krüpteerimisvõti, mille abil mälusttoodud krüpteeritud andmed dekrüpteeritakse, tööks
kasutatakse, seejärel uuesti krüpteeritakse ning mällu kirjutatakse. Sealjuures on kaitstud ainult
protsessor – mälu ning muud komponendid, kus krüpteeritud programm ja andmed paiknevad,
ei pea olema kaitstud. Tegemist on keeruka ent kahtlemata efektiivse võimalusega, mis lisaks
14
piraatkoopiate tegemise välistamisele ka dekompileerimist ja pöördprojekteerimist oluliselt ras-
kendab.
Üheks koopiate tegemise vastaseks meetmeks on andmekandjale maksimaalse võimaliku
installeerimiste arvu määramine. See eeldab tarkvara levitamist korduvkirjutataval andmekand-
jal nagu näiteks disketil. Iga kord, kui selliselt andmekandjalt toimub uus installeerimine, suu-
rendatakse loendurit ning kindlaks määratud arvu ületades enam järgnevaid installeerimisi ei
lubata. Antud meetodi töötamiseks peab olema loendurit sisaldav fail krüpteeritud ja hästi pei-
detud, et seda ei saaks muuta. Samuti on oluline, et andmekandjat ei saaks tavalisel viisil ko-
peerida, kuna sel juhul kaotaks loendur mõtte. Seda meetodit kasutatakse suhteliselt vähe, kuna
piirangu seab andmekandja korduvkirjutatavuse nõue. Samuti ei ole võimalik sel viisil kaitsta-
vat tarkvara levitada Interneti vahendusel, kuna tarkvara peab olema spetsiaalsel andmekandjal.
Pordiluku all mõistetakse mis tahes piraatlusevastast elektroonilist lisaseadet. Tänapäeval
on valdavalt kasutusel USB-porti paigaldatavad pordilukud, kuid on ka printeri või serial por-
ti kasutavaid seadmeid. Kaitstav tarkvara müüakse komplektina koos ainulaadse pordilukuga,
mille olemasolu programmi käivitamisel kontrollitakse ning selle mitteleidmisel programmi
käivitamine peatatakse. Kuigi enamasti on pordiluku ülesandeks kaitsta tarkvara ebaseaduslike
koopiate loomise eest, võib seda kasutada ka paljudel muudel eesmärkidel – tarkvara litsentsee-
rimine, andmebaasi juurdepääsu kontroll, erinevate loendurite rakendamine, versiooni kontroll
jne.
Pordiluku miinusteks on Interneti kaudu levitamise võimatus (iga tootega peab olema kaasas
kindel füüsiline seade), selle rakendamiseks võib vaja minna spetsiaalseid draivereid, iga seade
hõivab ühe pordi ning nende kasutamine võib olla tülikas. Oluline on, et rakendatavate meet-
mete efektiivsus ei sõltu mitte pordilukust, vaid tarkvarasse programmeeritud mehhanismide
keerukusest – kui kontroll- ja/või lukustusmehhanismid on kergesti kõrvaldatavad või väldita-
vad, ei ole ka pordilukust suuremat kasu.
Tarkvara installeerimise käigus võidakse luua juhuslik ning arvutisse krüpteeritud kujul pei-
detav seerianumber. Selleks, et saavutada programmi täielik funktsionaalsus või et üldse pro-
15
grammi käivitamine võimalik oleks, tuleb võtta ühendust tarkvara müüjaga, kes annab klien-
dile tema seerianumbrile vastava parooli. Programmi käivitamisel kontrollitakse seerianumbri
ja parooli vastavust, mille sobides programm käivitub. Selle meetmega kaasnevad ka omad
ebameeldivused – kuna seerianumbrit sisaldav fail paikneb kasutaja kõvakettal, tuleb nt peale
operatsioonisüsteemi vahetust või tarkvara uuesti installeerimist see ka uuesti registreerida, ku-
na seerianumber lihtsalt süsteemist kaob või genereeritakse uus ja senise parooliga mittesobiv
seerianumber. Samuti on võimalik seerianumbrit sisaldav krüpteeritud fail süsteemist üles leida
ning selle abil ikkagi ebaseaduslikke koopiad teha.
Vast kõige enam on tavakasutaja kokku puutunud nö cd-key’ga, mis kujutab endast tähtede
ja numbrite kombinatsiooni, mida nõutakse enne tarkvara installeerimise alustamist CD-lt. Kui
sisestatud sõne ei klapi CD-l oleva tarkvarasse sisseprogrammeerituga, installeerimisprotsess
katkestatakse. Olenevalt tarkvarast võib olla iga kasutaja jaoks eraldi cd-key või kõigile üks
ühine. Siiski ei ole seegi vahend eriti turvaline, kuna on võimalik kasutada ühte võtit piiramatu
arv kordi. See teeb kergeks piraatkoopia ja sellele sobiva võtme levitamise füüsilisel kujul või
ka Interneti teel.
2.3.2 Tarkvaralised meetmed
Tänapäeval on tarkvarakaitse riistvaraliste meetmete kasutamise esimeseks vastuargumendiks
Interneti teel tarkvara levitamise võimaluse välistatus, kuna kõik eelpool toodud meetmed eel-
davad mingit spetsiaalset andmekandjat või arvutiarhitektuuri. Kuigi riistvaraliste vahendite ka-
sutamine pakub seadusandlike meetmete kõrval tarkvarale lisakaitset, ei piisa tarkvara efektiiv-
seks kaitsmiseks ainult neist.
Tarkvara vastu on kolm põhilist erinevate eesmärkidega ründeviisi ning seetõttu on vaatluse
all ka kolm erinevat vastumeedet – vesimärgistamine (watermarking) piraatkoopiate tegemi-
se vastu, koodi terviklikkuse kontrollimine (integrity check) omavolilise modifitseerimise vastu
ning sogastamine (obfuscation) pöördprojekteerimise vastu. Neist kaks esimest saavad põgusalt
käsitletud käesolevas peatükis, sogastamisele on keskendatud kogu ülejäänud töö.
16
Vesimärgistamine
Igapäevases tähenduses mõistetakse vesimärgi (watermark) all tavaliselt vaevumärgatavat
kuid mingi kindla nurga alt silmaga nähtavat kujutist, mis tõendab eseme või toote autentsust.
Igaüks on näinud paberrahal või CD-karbi kleebisel olevat vesimärki. Need on füüsilised, käega
katsutavad kopeerimiskindlad ja raskesti võltsitavad, kuid digitaalse omandi kaitseks jääb neist
väheks – selleks on vaja digitaalset vesimärki. Edaspidi ongi kõne all digitaalsed vesimärgid.
Artiklis [5] on vesimärk kirjeldatud kui märk, mida iseloomustavad järgmised tunnused:
a) ta on integreeritud mingisse tehisesse (teksti, pilti, videosse, helisse) või intellektuaalses-
se omandisse (tarkvara, algoritm, andmestruktuur), b) ta on loodud identifitseerimaks autorit,
allikat, kasutatud vahendeid või märgistatud toodet, c) ta peab olema raskesti avastatav ja ee-
maldatav.
Artikli [9] järgi on välja toodud neli peamist vesimärgi jaotusviisi sõltuvalt nende eesmärkidest:
• Autori märk (authorship mark) lisab tarkvarasse autorit identifitseeriva informatsiooni.
• Sõrmejälje märk (fingerprint mark) lisab tarkvarasse informatsiooni seerianumbri näol,
mis võimaldab tuvastada tarkvara omanikku.
• Seaduslikkuse märk (validity mark) lisab tarkvarasse informatsiooni, mis võimaldab kind-
laks teha, kas oma olemuselt on tarkvara samal kujul, mis ta algselt oli.
• Litsentseerimise märk (licensing mark) sisaldab endas informatsiooni, kuidas võib antud
tarkvara kasutada.
Sõrmejäljestamine (fingerprinting)
Sageli räägitakse sõrmejäljestamisest kui täiesti iseseisvast teemast, kuid sisuliselt on tege-
mist vesimärgistamisega, väikese nüansiga, et igasse koopiasse tarkvarast lisatakse unikaalne
märgend, mis lubab lisaks varguse avastamisele leida ka tarkvara esialgse ebaseadusliku levita-
ja. Tüüpiline “sõrmejälg” sisaldab endas müüja, toote ja ostja identifitseerimise numbreid.
17
Kuigi sõrmejäljestamine võimaldab saada rohkem informatsiooni tarkvara väärkasutamise
kohta kui tavaline vesimärgistamine, on meetme peamine hüve (iga toode on identifitseeritav) ka
selle nõrkuseks. Vesimärki eemaldada soovival isikul on võimalus muretseda mitu eksemplari
antud tarkvarast ning neid võrreldes leida erinevused koodis, seega leida unikaalsete sõrmejäl-
gede asukohad ning need eemaldada2.
Vesimärgi omadustest tähtsamatena tuuakse reeglina välja järgmised kolm:
• Vesimärgi asukoht peab olema usaldusväärselt leitav ning ta peab olema ekstraheeritav ka
pärast programmi töötlemist selliste semantikat säilitavate teisenduste rakendamist nagu
seda on optimeerimine ja sogastamine (inglisekeelne vastav termin resilience).
• Peidetud andmete maht (data rate). Oluliseks omaduseks on lisakoormus, mis kaasneb
vesimärgi lisamisega programmi sh koodi suurus, mälu kasutus, programmi töö kiirus.
Samuti on oluline, kui suur on vesimärk võrreldes programmi endaga ning see, et võima-
likult väikseks jäädes sisaldaks see võimalikult palju informatsiooni.
• Vesimärgi läbipaistvus (stealth). Vesimärgi lisamine programmi ei tohi muuta mingeid
statistilisi väärtusi ning andmed peavad olema vaatlejale nähtamatud. Programmi tööks
vajalikud instruktsioonid ning vesimärki realiseerivad instruktsioonid peavad olema või-
malikult eristamatud.
Lisaks ülalnimetatud kolmele omadusele on artiklis [10] välja toodud veel kaks omadust:
• Vesimärgil peab olema mingi matemaatiline omadus, mis võimaldaks vesimärgi ekstra-
heerimisel tõestada, et tegemist on tahtliku akti tulemusega, mitte juhusliku väljundi või
veaga.
• Märk ei tohi mõjutada programmi efektiivsust (peab kasutama vähe ressursse).
Vesimärgid jagunevad oma olemuselt kaheks – staatilised ja dünaamilised vesimärgid.
2 Inglise keelses kirjanduses viidatud kui collusion attack.
18
Staatilised vesimärgid
Staatilised vesimärgid on realiseeritud programmi lähtekoodis, objektkoodis või täitmis-
failis. Java koodi puhul võib vesimärgi peita suvalisse class-faili ossa – konstantide, meetodite,
reanumbrite jne tabelitesse. Staatilised vesimärgid jagunevad omakorda andme- (data) ja koodi-
(code) vesimärkideks. Kuigi need mõlemad on lihtsad ja populaarsed, ei ole neist suuremat ka-
su – vesimärgid võib hävitada näiteks optimeerimine või sogastamine.
Dünaamilised vesimärgid
Kui staatilised vesimärgid on olnud kasutusel juba mõnda aega, siis tarkvara dünaamili-
sed vesimärgid on suhteliselt uus nähtus (käsitletakse põhjalikumalt artiklis [11]) ning on veel
vähem tähelepanu saanud kui staatilised vesimärgid. Dünaamilised vesimärgid avalduvad pro-
grammi seisundis (state), mitte aga programmikoodis endas. See teeb lihtsamaks vesimärkide
modifitseerimiskindlaks muutmise, mis on oluline vesimärkide kaitse seisukohalt. Dünaamilisi
vesimärke on [11] põhjal kolme tüüpi – üllatusmuna vesimärk (Easter Egg watermark), and-
mestruktuuri vesimärk (data structure watermark) ning käivitamise jälje vesimärk (execution
trace watermark). Nende kõigi ühiseks jooneks on, et programm jookseb mingi ettemääratud
sisendi abil seisu, mis kujutabki endast vesimärki. Meetodid erinevad üksteisest selle poolest,
millises programmi seisundis vesimärki hoitakse ning kuidas see avaldub.
Tervikluse kontroll
Riistvaralistest meetmest rääkides sai mainitud, et modifitseerimise vastast kaitset annavad
spetsiaalsed protsessorid, mis loovad programmile turvalise töökeskkonna, ning ebaturvalises
mälus hoitakse vaid krüpteeritud andmeid, kuid nende laialdast levimist takistab kõrge hind.
Kõik ülejäänud eelpool mainitud kaitsemeetmed ei takista aga otseselt modifitseerimise katsete
tegemist. Selleks, et vältida tarkvarasse muudatuste tegemise võimalust, on vaja võtta kasutu-
sele tervikluse kontroll.
19
Põhjuseid, miks halvata programmi töö muudatuste avastamisel, on mitmeid:
• Kui tahetakse koodist eemaldada kaitsemehhanisme (vesimärgid, seerianumbri kontroll
jne).
• Kui e-äri multimeedia tootelt püütakse eemaldada turvamehhanisme.
• Kui koodi püütakse lisada midagi (viirused jms).
Tervikluse kontrolli ülesandeks on avastada programmi väärkasutusi, mis enamasti tähen-
dab koodi muutmiskatseid, ning seejärel vastavate meetmete rakendamine. Siinkohal eristatakse
staatilist ja dünaamilist tervikluse kontrolli – staatiline kontroll viiakse läbi ainult programmi
käivitamisel, dünaamilist kontrolli teostatakse kogu programmi töösoleku ajal. Autoriseerimata
muutmiskatsetele võib järgneda ründajale märkamatuks jääv logisse kirjutamine, teate saatmi-
ne, programmi töö täielik halvamine või muu.
Artiklis [10] on modifitseerimise vältimise viisidena toodud kolm järgmist:
• Programmi identsuse võrdlemine originaaliga nt MD5 algoritmi abil;
• Programmi vahetulemuste kontrollimine (result checking);
• Programmi krüpteerimine. Seejuures dekrüpteerimine peab olema kaitstud riistvaraliste
vahenditega ja/või sogastamise abil.
Sageli on tavapärastest kontrollmehhanismidest (seerianumbri, parooli jne kontroll) kõrvale-
hiilimine lihtne, kuna kogu turvalisus koondub ühte punkti. Kui tahes keerukatele ja põhjalikele
kontrollidele järgneb viimaks alati otsustus, kas anda kasutajale programmi kasutamise õigus
või mitte. Seetõttu ei olene eelnevatest turvaprotseduuridest midagi, kui õnnestub muuta seda
viimast otsust. Sellest nõrkusest ülesaamiseks on tervikluse kontroll ning artiklis [6] tutvustatud
valvurid.
Valvuriks nimetatakse koodijuppi, mis on vastutav programmi töösoleku ajal mingi kindla
turvaülesande täidesaatmise eest. Valvurite kaheks põhiülesandeks on kontrollsumma arvuta-
mine ning koodi parandamine. Kontrollsumma arvutamise abil kontrollitakse mingi kindlaks
määratud koodiosa terviklikkust. Selles koodiosas tehtud muudatuste tagajärjel muutub kont-
rollsumma ning erinevuse avastades käivitab valvur soovitud kaitsemehhanismi.
20
Koodi parandavad valvurid viivad modifitseeritud koodi esialgsele kujule enne kui seda ka-
sutama hakatakse. See võimaldab jooksutada programmi ka peale muutmist kui muutmata ver-
siooni. Üheks koodi parandamise võimaluseks on muudetud koodi ülekirjutamine kuskil mujal
säilitatud koopiaga. Artiklis [7] tutvustatakse oma tööpõhimõttelt valvuritele sarnanevaid teste-
reid (tester).
Valvurite töö tõhusamaks muutmiseks kasutatakse reeglina neid hulganisti. Seejuures kont-
rollivad nad nii etteantud koodisektsioonide terviklikkust kui ka üksteist. Selleks, et edukalt
koodi muuta, on vaja üles leida ja kahjutuks teha kõik programmis olevad valvurid.
Erinevalt monoliitsetest kontrollmehhanismidest pakuvad valvurid (ja ka testerid) paremat
kaitset, kuna neid iseloomustab [6]:
• Hajusus (distributedness). Ei ole üksikut kohta, mida murdes oleks võimalik alistada kogu
turvasüsteem.
• Arvukus (multiplicity). Ühte koodijuppi võib kontrollida palju erinevaid valvureid ning
erineval viisil.
• Dünaamilisus (dynamism). Valvurite võrgu konfigureerimiseks on mitmeid võimalusi.
• Skaleeritavus (scalability). Alati on võimalik suurema turvalisuse huvides valvureid juur-
de lisada.
Hoolimata loetletud positiivsetest külgedest, on ka tervikluse kontroll kõrvaldatav, kui se-
da realiseerivad koodisegmendid on kergesti leitavad. Tervikluse kontrolli, vesimärke, salajasi
algoritme jms aitab peita kolmas tarkvaraline kaitsemeede – sogastamine. (Tegelikult on sogas-
tamisele pandud veel lootusi ka muudes valdkondades, kuid neist lähemalt järgmistes peatükki-
des.)
21
3 Ülevaade sogastamisest
3.1 Sogastamise olemus ja kasutusvaldkond
Nagu eelnevalt öeldud, käsitletakse intellektuaalse omandi tarkvaraliste kaitsemeetmetena sa-
geli üheskoos vesimärgistamist, tervikluse kontrolli ning sogastamist.
Olenevalt taotletavast eesmärgist võimaldab vesimärgistamine ([9], [10], [11], [12]) tuvas-
tada tarkvara autorit, tarkvara õigusjärgset omanikku, litsentsi olemasolu, konkreetse toote uni-
kaalset seerianumbrit jms. Tervikluse kontrolli ([6], [7]) peamiseks ülesandeks on avastada tark-
vara väärkasutusi ning neile vastavalt reageerida. Kuna programmikoodi omavoliline muutmine
on sageli eelnevaks sammuks tarkvara (edasisele) väärkasutusele, võib kokkuvõtlikult öelda, et
vesimärgistamise ja tervikluse kontrolli ülesandeks on tarkvara kaitsmine piraatkoopiate tege-
mise, nende levitamise ja kasutamise eest.
Samas ei pruugi ründaja eesmärgiks olla sugugi mitte tarkvarast piraatkoopia tegemine ja
selle levitamine (müük), vaid hoopis selle mingi algoritmi, disainielemendi või tööpõhimõtte
teadasaamine, et neid teadmisi ära kasutades omi ressursse kokku hoida ning samalaadne toode
luua. Kuigi ka tervikluse kontrolli ja vesimärke realiseerivad koodisegmendid luuakse reegli-
na võimalikult läbipaistvad (ründajale märkamatud), ei ole siiski nende peamiseks eesmärgiks
kaitsta strateegiliselt tähtsaid algoritme või muid programmielemente. Algoritmide kaitseks on
vaja mingit muud kaitsemeedet. Siinkohal on suured lootused pandud sogastamisele kui pöörd-
projekteerimise vastasele kaitsemeetmele.
Pöördprojekteerimine võib olla ründe põhieesmärgiks, kuid enamasti on see kõigest vahe-
etapiks enne koodi modifitseerimist, et tutvuda programmi tööpõhimõtetega. Selleks, et pöörd-
projekteerimine oleks võimalikult kulukas, kasutatakse tarkvara sogastamist. Sealjuures ei ole
sogastamise eesmärgiks sageli mitte terve programmikoodi loetamatuks muutmine (terve koodi
kopeerimise eest kaitseb “Autorõiguse seadus” ning samuti on sellist rikkumist kergem avasta-
da), vaid ainult mingite kindlate, ründajale potentsiaalselt enim kasutoovate koodisegmentide
peitmine. Ka on üheks sogastamise efektiivsust hindavaks näitajaks sogastava teisenduse välja-
paistmatus. Parimal juhul ei tohiks sogastatud koodilõik olla ülejäänud koodist eristatav.
22
Hoidudes hetkel formaalsetest definitsioonidest, võib öelda, et sogastamise eesmärgiks on
luua esialgsest programmist sogastatud programm selliselt, et [10]:
• Sogastavad muutmised ei muudaks programmi käitumist – st oleksid semantikat säilita-
vad (semantics preserving).
• Sogastatud programm peab olema ründajale võimalikult arusaamatu – sogastatud pro-
grammi pöördprojekteerimine peab olema rangelt aeganõudvam esialgse programmi pöörd-
projekteerimisest (obscurity).
• Muudatuste tagasimuutmine (deobfuscation) peab olema automaatse vahendi abil võima-
tu või äärmiselt aeganõudev (resilience).
• Muudatused peavad jääma võimalikult märkamatuks (stealth).
• Muudatustega kaasnevad lisakulutused programmi töös peavad olema minimaalsed (cost).
Veidi konkreetsema, kuid endiselt mitteformaalse definitsiooni kohaselt on sogastaja Oprogramm, mis võtab sisendiks programmi P ning genereerib sellest uue programmi O(P ),
mis rahuldab järgmist kahte tingimust:
• Funktsionaalsus – O(P ) arvutab sama funktsiooni mis P ;
• Virtuaalse musta kasti omadus – ükskõik, mis on arvutatav sogastatud programmistO(P ),
on arvutatav P -oraaklipääsuga.
Kõige ilmsemaks sogastamise kasutamise valdkonnaks on tarkvarakaitse. Samas oleks ar-
tikli [8] kohaselt sogastajad rakendatavad ka näiteks homomorfsete krüpteerimisalgoritmide
loomisel või salajase võtme avalikuks võtmeks muutmisel.
3.2 Sogastamise käsitletus kirjanduses
Igale programmeerimisega kokkupuutunud inimesele on teada kui keeruline võib olla võõrast
programmist arusaamine ilma vastava dokumentatsiooni, seletavate kommentaaride, tabulat-
sioonide jm koodi lugemist hõlbustavate vahenditeta. Segasus on programmikoodi “loomulik”
23
olek ning see on ka ehk üheks kergemini adutavaks põhjuseks, miks üldse sogastamisest intel-
lektuaalse omandi kaitsel abi võiks loota.
Varasematel aegadel levitati tarkvara suurelt jaolt masinkoodis ning monoliitsena, mis tegi
pöördprojekteerimise keeruliseks (ehkki mitte võimatuks), ning seetõttu ei olnud pöördprojek-
teerimise oht tarkvaratootjatele primaarseks probleemiks. Seoses enda baitkoodis suhteliselt
palju metainfot kandvate java ja .NET programmide populaarsuse kasvuga hoogustus ka sogas-
tamise praktiline kasutamine ning selle käsitlemine kirjanduses.
Teisest küljest kasvatas huvi sogastamise, aga ka muude tarkvaraliste kaitsemeetmete, vastu
“uus” turvalisuse aspekt - kui varem oli peamiseks turvaprobleemiks arvuti (host’i) kaitsmine
kahjulike klientprogrammide (malicious client) eest, siis mobiilsete agentide (mobile agents)
leviku kasvuga lisandus klientprogrammide kuritahtliku keskkonna (malicious hosts) eest kaits-
mise probleem. Paljud artiklid on kirjutatud just mobiilsete agentide kaitse seisukohast
Viimase paarikümne aasta jooksul on paljud klassikalised krüptograafia probleemid (nt
krüpteerimine, autentimine jt) saanud keerukusteooria alused. Sogastamisel aga teoreetilised
alused praktiliselt puuduvad. Kuigi leidub ka üksikuid erandeid, jääb enamik sogastamist puu-
dutavast akadeemilisest kirjandusest viimase kümne aasta piiresse - eelmise sajandi 90ndate
aastate teisest poolest kuni tänapäevani. Kahekümnenda sajandi lõpul käsitleti sogastamist ar-
vukates heuristilist laadi töödes (nt [13], [14], [15] jt), ent hoolimata sellest, et neis ja muudes
artiklites kirjeldatud teisendused paistavad efektiivsed ja kasulikud, on kõigi ühiseks puuduseks
see, et neil puudub teoreetiline põhi, mis garanteeriks ja tõestaks nende sogastavate muudatuste
efektiivsust.
Hoopis uued tuuled hakkasid puhuma peale 2001. aasta augustis toimunud Crypto konve-
rentsi. Nimelt esitati seal grupi matemaatikute ja krüptoloogide poolt formaalne tõestus ideaalse
sogastamise võimatusest [8]. Sellest hetkest alates võib ehk täheldada teema veidi passiivsemat
käsitlemist kirjanduses ning akadeemilistes ringkondades hakati sogastamist vaatama uues val-
guses – püütakse kitsendada rakenduste klasse, mille jaoks leiduks turvaline sogastaja, näida-
takse, et saavutatud tulemus ei lähe vastuollu artiklis [8] toodud kontranäitega jne.
24
Mida ideaalse sogastamise võimatus praktikas tähendab ja endaga kaasa toob, on käsitletud
peatükis 4.7. Esmalt aga veidi lähemalt artikli [8] põhitulemusest.
3.3 Sogastamise võimatus
Standardse definitsiooni järgi on sogastatud programmi näol tegemist nö virtuaalse musta kasti-
ga (virtual black box). St, et kõik, mida keegi suudab efektiivselt arvutada sogastatud program-
mist, peab olema arvutatav ka ainult programmi sisendit/väljundit uurides ehk oraaklipäringuid
kasutades. Nii on ideaalselt sogastatud programm otseselt võrreldav mütoloogilise oraakliga –
esitades oraaklile küsimuse (sisendi), saame vastuse (väljundi), kuid ei õpi absoluutselt mitte
midagi selle kohta, kuidas vastus leiti. Samas peab kõige selle juures olema täidetud funktsio-
naalsuse tingimus – sogastatud programm peab arvutama täpselt sama funktsiooni, mis sogas-
tamata programmgi ning tegema seda efektiivselt3.
Artikli [8] autorid tõestasid, et standardse musta kasti omadusest lähtudes on programmi
täielik sogastamine võimatu. Selleks konstrueeriti funktsioonide pere F , millesse kuuluvad
funktsioonid on selles mõttes sogastamatud, et leidub mingi omadus π : F → 0, 1 nii, et:
• Mistahes funktsiooni f ∈ F arvutavast programmist või Boole’i skeemist on väärtus
π(f) alati leitav.
• Ei ole olemas algoritmi, mis omades ainult oraaklipääsu suvalisele funktsioonile f ∈ Fsuudaks arvutada omadust π(f) paremini lihtsalt juhuslikust arvamisest.
Selliste funktsioonide olemasolu tähendaks, et kui tahes sogastatud programmist on väär-
tus π(f) igal juhul leitav, kuid erinevalt musta kasti definitsiooni põhjal tehtud eeldusest ei ole
see leitav oraaklipääsu abil. St, et ei ole võimalik sogastada selliseid funktsioone sisaldavaid
programme isegi mitte siis, kui sogastamise eesmärgiks on peita kasvõi üksainus bitt (antud ju-
hul π(f)). Sellest järelduvalt väidavad autorid, et virtuaalse musta kasti omaduse definitsioonis
tarkvara sogastamise puhul on miski “sünnipäraselt vigane”. Näitamaks, et tegemist pole siiski
3 Tegelikult on erinevatel autoritel programmi funktsionaalusest veidi erinev käsitlus, kuid neist lähemalt taga-
pool.
25
vaid definitsiooni tõlgendamisega mängimisega, on lisaks formaalsele tõestusele tõestatud ar-
tiklis ka mõnede sogastajate rakenduste võimatus. Sogastamise võimatuse tõestuse käiku ning
kasutatud vahendeid käsitletakse lähemalt järgmises peatükis.
26
4 Sogastaja võimatuse formaalne tõestus
Käesolevas peatükis on refereeritud artiklis [8] tõestatud ideaalse sogastaja (edaspidi lihtsalt so-
gastaja) eksisteerimise võimatus. Tõestuse tulemusena ilmneb, et leidub sogastamatute funkt-
sioonide pere, mille tõttu peame hülgama lootuse, et võiks leiduda suvalisest programmist vir-
tuaalset musta kasti loovat sogastamistehnikat. Artiklis on tulemus tõestatud nii Turingi masi-
nate kui ka loogikaskeemide (Boole’i skeemide) abil esitatud programmide korral. Lihtsuse ja
lühiduse huvides piirdume enamalt jaolt Turingi masinate abil läbi viidud tõestuse refereerimis-
ega, kuid päris mööda minna ei saa ka Boole’i skeemidest.
4.1 Tähistused
Esmalt olgu toodud tõestuses kasutatud tähistused ja lühendid ning mõningad seletused.
TM on edaspidi aeg-ajalt kasutatav lühend Turingi masinale. PPT (probabilistic polynomial-
time TM) tähistab tõenäosuslikku polünomiaalse keerukusega Turingi masinat4. Tõenäosuse
tähistamiseks on võimaliku segaduse vältimiseks kasutatud inglisepärast lühendit Pr eestipä-
rase TN asemel. Boole’i skeem (boolean circuit ehk lihtsalt circuit) – Boole’i loogika kolme
põhitehet JA, VÕI ja EI teostav skeem. Kui C on loogikaskeem n sisendi ja m väljundiga ja
x ∈ 0, 1n, siis C(x) abil tähistame me loogikaskeemi C töö tulemust sisendil x. Ütleme, et
C arvutab funktsiooni f : 0, 1n → 0, 1m, kui iga x ∈ 0, 1n korral C(x) = f(x).
Algoritmide A, M ja sõne x korral tähistame AM(x)-ga funktsiooni M : 0, 1∗ → 0, 1∗
oraaklina5 kasutava algoritmi A väljundit sisendi x korral – st, et algoritmi A on laiendatud
eriliste M -käskudega, mis arvutavad M väärtuse ühe sammu jooksul. Kui M on mingit funkt-
siooni realiseeriv Boole’i skeem, siis kannab AM(x) standardset tähendust – vastuseks oraakli-
päringule x saab A skeemi väärtuse kohal x ehk M(x)-i. Oraaklipäringu all mõistame oraaklile
vastuse saamise eesmärgil sisendi andmist, kusjuures oraaklipoolne arvutuskäik jääb päringu
esitaja eest täielikult varjatuks. Olukorda, kus programmi P kasutatakse oraaklina, nimetame
4 Tõenäosuslikuks Turingi masinaks nimetatakse masinat, mille puhul käikude vahel valimine võib olla juhuslik
valik lõplikust hulgast võimalustest.5 Oraakli mõiste võttis kasutusele A. Turing tähistamaks sellega teoreetilist Turingi masina osa, mis arvutab
vastuse mis tahes probleemile (ka mittearvutatavele) ühe sammu jooksul.
27
sageli P -oraaklipääsuks või juurdepääsuks P -le oraaklina. Kui M on Turingi masin, siis tähen-
dab AM(x), et A võib teha oraaklipäringuid kujul (x, 1t) ning saada vastuseks, kas masina M
väljundi sisendi x korral (juhul, kui masin M peatub antud sisendi korral t sammu jooksul), või
⊥ juhul, kui masin M(x) ei peatu t sammu jooksul.
Kui A on tõenäosuslik TM siis A(x; r) abil tähistame A töö tulemust kasutades sisendit x ja
juhuslikku linti6 r. A(x)-ga on tähistatud jaotus, mis on saadud järgmiselt – 1) genereeritakse
ühtlase jaotusega juhuslik suurus r, 2) arvutatakse kõnealuse jaotusega juhulik suurus A(x; r).
Kui D on jaotus, siis xR← D tähistab asjaolu, et juhuslik suurus x on jaotusega D. Kui S on
mingi hulk, siis xR← S tähistab asjaolu, et x on ühtlase jaotusega sellel hulgal – st võrdse tõe-
näosusega võib võtta ükskõik millise hulga S elemendi väärtuse. Supp(D) tähistab jaotuse D
toetust – piirkond, kus jaotusega D juhuslikul suurusel on positiivsed (nullist erinevad) esine-
misvõimalused.
f = O(g) ⇔ ∃c ∈ R, k0 ∈ N nii, et ∀k > k0 korral f(k) ≤ c · g(k). Keerukuse alampii-
ri kirjeldamiseks kasutatakse Ω-tähistust: f(k) = Ω(k), kui leiduvad reaalarvud c ja k0 nii,
et f(k) ≥ ck iga k ≥ k0 korral. f(k) = Θ(g(k)) parajasti siis, kui f(k) = O(g(k)) ja
f(k) = Ω(g(k)), mis tähendab, et f(k) on piiratud ülevalt funktsiooniga c1 · g(k) ning alt
funktsiooniga c2 · g(k), kus c1 ja c2 on mingid konstandid.
Funktsioon µ : N → N on kaduvväike (tähistame neg(k) tulenevalt inglise keelsest termi-
nist negligible), kui see kahaneb kiiremini kui ükskõik millise polünoomi pöördfunktsioon. St
iga positiivse polünoomi p(·) korral leidub N ∈ N nii, et µ(n) < 1/p(n), iga n > N . Suvaline
kaduvväike funktsioon on tähistatud neg(·) abil.
Turingi masinad ja loogikaskeemid on esitatud kanoonilisel kujul sõnedena hulgast 0, 1∗.
Kui M on TM siis 〈M〉 tähistab funktsiooni 〈M〉 : 1∗ × 0, 1∗ → 0, 1∗ nii, et
6 Juhuslik lint (random tape) – tõenäosusliku Turingi masina M osa, milles on salvestatud M ’i poolt kasuta-
tavad juhuslikud bitid. Sisuliselt on tegemist juhuarvuga, mille abil saab tõenäosuslikku masinat M modelleerida
deterministliku masina N abil.
28
〈M〉(1t, x)def=
y kui M(x) lõpetab töö t sammu jooksul
⊥ muudel juhtudel.
4.2 Sogastaja
Selleks, et tõestada virtuaalse musta kasti omadusel baseeruva sogastaja võimatust, tuleb
esmalt anda sellise sogastaja mõistele formaalne kuju. Nagu öeldud, tähendab virtuaalse mus-
ta kasti omadus, et kõik sogastatud programmi O(P ) abil arvutatav peab olema arvutatav ka
P -oraaklipääsuga. Antud seisukohast lähtuvalt saame defineerida sogastajale kehtivad erineva
tugevusega turvanõuded nende üldisuse kahanevas järjekorras:
• (arvutuslik eristamatus) Kõige üldisem ja seega kõige tugevam nõue on, et kõike, mida
saab efektiivselt leida sogastatud programmist O(P ), saab leida ka P -oraaklipääsu abil.
Seejuures peab sogastatud programmist arvutatu olema eristamatu oraaklipääsuga arvu-
tatust täpsustamata, mida vastane püüab arvutatada.
• (relatsiooni rahuldamine) Järgmiseks võimaluseks on nõuda, et püüdes leida kahe pro-
grammi vahelist relatsiooni rahuldavat väljundit, oleks P -oraaklipääsuga õnnestumise
tõenäosus võimalikult võrdne tõenäosusega saavutada edu andes vastasele programmi
O(P ).
• (funktsiooni arvutamine) Eelnevast kitsam on eelmise nõude tingimuste rahuldamine ju-
hul, kui vastase eesmärk on arvutada sogastatud programmist mingit funktsiooni.
• (predikaadi arvutamine) Kõige nõrgem on nõue kui vastane üritab arvutada mingi pre-
dikaadi (funktsiooni omaduse) tõeväärtust, siis tõenäosus leida see väärtus P -oraakli-
pääsuga erineks väga vähe tõenäosusest leida see väärtus sogastatud programmist O(P ).
Kuna meie eesmärk on tõestada üldotstarbelise sogastaja (st sogastaja, mis töötaks iga pro-
grammi peal) võimatus, on tõestus kõige tugevam, kui kasutatakse kõige nõrgemat turvanõuet
ning näidata, et ka see ei ole saavutatav.
Sellest arutelust lähtudes saame programmide (esitatud Turingi masinatena) sogastaja jaoks
järgneva definitsiooni:
29
Definitsioon 1. (Turingi masina sogastaja) Tõenäosuslik algoritmO on TM sogastaja, kui keh-
tivad järgmised kolm tingimust:
• (funktsionaalsus) Iga Turingi masina M puhul tähistab sõne O(M) TM-t, mis arvutab
sama funktsiooni, mis M .
• (polünomiaalne aeglustumine) Masina O(M) pikkus ja tööaeg on kõige halvemal juhul
polünomiaalselt suurem masina M samadest näitajatest. St, et iga TM M korral leidub
mingi polünoom p selliselt, et∣∣O(M)
∣∣ ≤ p(|M |) ja kui M peatub sisendi x korral t
sammu järel, siis sama sisendi korral peatub O(M) p(t)sammu järel.
• (virtuaalse musta kasti omadus) Iga PPT A korral leidub PPT S ja mingi kaduvväike
funktsioon α suvalise TM M jaoks nii, et:
∣∣∣ Pr[A(O(M)) = 1
]− Pr[S〈M〉(1|M |) = 1
]∣∣∣ ≤ α(|M |) .
Me ütleme, et O on tõhus, kui tema tööaeg on polünomiaalne.
Kuigi enamus tõestuse käigust baseerub Turingi masinatel, on meil vaja ka Boole’i skeemi
sogastaja definitsiooni.
Definitsioon 2. Tõenäosuslik algoritm O on Boole’i skeemi sogastaja, kui kehtivad järgnevad
kolm tingimust:
• (funktsionaalsus) Boole’i skeemi C puhul tähistab sõne O(C) skeemi, mis arvutab sama
funktsiooni, mis C.
• (polünomiaalne aeglustumine) Leidub mingi polünoom p iga C jaoks selliselt, et∣∣O(C)
∣∣ ≤ p(|C|)
• virtuaalse musta kasti omadus) Iga PPT A korral leidub PPT S ja mingi kaduvväike
funktsioon α suvalise Boole’i skeemi C jaoks nii, et:
∣∣∣ Pr[A(O(C)) = 1
]− Pr[SC(1|C|) = 1
]∣∣∣ ≤ α(|C|) .
Me ütleme, et O on tõhus, kui tema tööaeg on polünomiaalne.
30
Esimese tingimuse kehtimise vajalikkus on ilmselge, kuna arusaadavalt ei ole meil mida-
gi peale hakata sogastajaga, mis turvalisust pakkuda püüdes sogastatava TM-a (programmi)
funktsionaalsuse hävitab. Samuti on mõistlik halvimal juhul tööaja polünomiaalse suurenemi-
sega rahuldumine. Esmapilgul võibolla mitte nii kergesti mõistetav on kolmas tingimus, mille
mõte on järgmine: kui leidub mingi efektiivne algoritm A, mis suudab klassifitseerida uuritava
Turingi masina M ühte kahest klassist, siis leidub ka veel mingi teine algoritm S, mis suu-
dab seda enamvähem sama suure tõenäosusega kasutades Turingi masinat 〈M〉 oraaklina. See
tähendab, et nende kahe algoritmi eduka töö tõenäosused erinevad vaid kaduvväikese suuruse
α(|M |) poolest. S-le sisendiks antav unaarne suurus 1|M | (või 1|C| Boole’i skeemide puhul) tä-
histab talle antavat tööaega ehk sisuliselt sogastaja turvaparameetrit, mille suurendamisega on
võimalik saavutada kõrgemat turvalisust.
Eespool toodud mitteformaalse musta kasti omaduse käsitlusest lähtub veel üks võimalik
formulatsioon. Kergesti on nähtav, et mingi predikaadi π puhul on tõenäosus, et A(O(M)) =
π(f) sama, mis Pr[S|C|(1|C|) = 1
]pluss mingi kaduvväike suurus. See tähendab, et tõenäosus
leida sogastatud programmist O(M) predikaadi π tõeväärtus on umbkaudu võrdne tõenäosuse-
ga leida see M -oraaklipääsuga.
Olgu veel märgitud, et peamine erinevus Turingi masinate ja Boole’i skeemide vahel on
asjaolu, et lint, millel töötab TM, võib olla sisuliselt lõpmatu pikkusega. Samas Boole’i skee-
mi sisendite arv on alati fikseeritud suurusega. Seetõttu on intuitiivselt mõistetav, et Turingi
masina sogastamine on keerulisem loogikaskeemi sogastamisest. Seega, kui peaks olema või-
malik konstrueerida ideaalne Turingi masina sogastaja, on alust arvata, et selline eksisteerib ka
Boole’i skeemide jaoks. Kuna meie eesmärk on tõestada selliste sogastajate võimatust, siis ol-
les tõestanud Boole’i skeemide sogastaja võimatuse, võime öelda, et tulemus kehtib ka Turingi
masinate puhul.
Autorid märgivad veel, et hoolimata sellest, et definitsioonidele 1 ja 2 vastava sogastaja
poolt pakutav turvalisus oleks mitmete praktikas kasutatavate rakenduste tarbeks ebapiisav, ei
ole ka sellistele definitsioonidele vastavat sogastajat võimalik luua.
31
4.3 Sogastaja võimatus
Selleks, et tõestada sogastaja võimatust, läheb vaja sogastamatute funksioonide peret.
Definitsioon 3. Sogastamatute funktsioonide pere Hkk∈N on jaotuste Hk pere üle lõplike (nt
0, 1lin(k) kuni 0, 1lout(k))7 funktsioonide , mis rahuldab tingimusi:
• (efektiivne arvutatavus) Iga funktsioon fR← Hk on arvutatav polünomiaalse suurusega
Boole’i skeemi poolt.
• (sogastamatus) Eksisteerib funktsioon π :⋃
k∈N Supp(Hk) → 0, 1 nii et:
1. π(f) on raskesti arvutatav f -oraaklipääsuga: iga PPT S korral
Prf
R←Hk
[Sf (1)k = π(f)] ≤ 1
2+ neg(k) .
2. π(f) on kergesti arvutatav omades juurdepääsu mis tahes funktsiooni f arvutava-
le skeemile: leidub PPT A selliselt, et iga f ∈ ⋃k∈N Supp(Hk) ja funktsiooni f
arvutava skeemi C korral
A(C) = π(f) .
Olgu siinkohal lisatud mõni märkus toodud definitsiooni selgituseks. Esimene tingimus tä-
hendab, et leidub Boole’i skeemide pere Ck(x)k∈N nii, et iga sisendi x ∈ 0, 1k korral
f(x) = Ck(x), kusjuures skeemi suurus on polünomiaalne. Lisaks sellele leidub efektiivne
algoritm S, mis sisendi (1k) korral väljastab Boole’i skeemi Ck(x), nii et S(1k) väljundjaotus8
langeb kokku pere Hk väljundjaotusega. See tähendab, et S suudab väljastada funktsioonide
"kirjeldusi", nii et nendele kirjeldustele vastavad funktsioonid esinevad sama jaotusega, nagu
nad oleksid juhuslikult genereeritud H abil.
Supp(Hk) tähistab komponentfunktsiooni Hk kandjat – st hulka, kus funktsioon on mää-
ratud ja nullist erinev. Kõne all olev hulkade ühend esitab seega kogu funktsioonide pere Hkandjat. Teise tingimuse esimene punkt tähendab, et ainult oraaklipääsu omades, ei ole funkt-
siooni π(f) väärtuse leidmise tõenäosus parem juhuslikust arvamisest.
7 lin(k) ja lout(k) on funktsioonide pere väljundi ja sisendi pikkusi kirjeldavad polünoomid.8 Boole’i skeemide kirjeldusi saab esitada kui sõnesid (bitistringe) mingis keeles L. Kuna kõigi bitistringide
hulgal saab defineerida tõenäosusjaotusi, saab tõenäosusjaotusi defineerida ka Boole’i skeemide hulgal.
32
Tõestuse käik
Definitsioonile 3 vastava sogastavate funktsioonide pere olemasolu näitamiseni jõuame
samm-sammult. Esmalt anname definitsiooni 1 eeskujul kahe Turingi masina sogastaja defi-
nitsiooni ning näitame sellele vastava sogastaja eksisteerimise võimatust. Seejärel kohandame
ühe Turingi masina sogastaja mitteeksisteerimise näitamiseks tõestuse konstruktsiooni, kombi-
neerides omavahel eelnevalt kasutatud kaks TM-t. Järgmise sammuna tõestame lemma 1 abil,
et kui eksisteerivad ühesuunalised funktsioonid, siis ei leidu Boole’i skeemi sogastajat ning
lemma 2 abil näitame Boole skeemi sogastaja võimatust tingimusteta. Tõestuste jada tipneb
sogastamatute funktsioonide pere olemasolu näitamisega (teoreem 3).
4.4 Kahe TM sogastamine
Ülalpool toodud Turingi masina sogastaja definitsioon kehtib ühe Turingi masina sogasta-
mise korral, kuid definitsioonis ei ole öeldud midagi juhtumi kohta, kus vastasel on kasutada
uurimiseks mitu Turingi masinat. Seetõttu defineerime esmalt kahe Turingi masina sogastaja,
näitame, et selle konstrueerimine on võimatu, millest saame hea lähtepunkti tõestamaks ühe
Turingi masina sogastaja võimatust.
Definitsioon 4. (Kahe TM sogastaja) Kahe TM sogastaja on defineeritud täpselt samamoodi
kui eelnevalt toodud TM sogastaja (def. 1), kuid tugevdatud on virtuaalse musta kasti omaduse
nõuet järgmisel moel:
• Iga PPT A korral leidub PPT S ning kaduvväike funktsioon α suvaliste Turingi masinate
M ja N jaoks selliselt, et:
∣∣∣ Pr[A(O(M),O(N)) = 1
]− Pr[S〈M〉,〈N〉(1|M |+|N |) = 1
]∣∣∣ ≤ α(min|M |, |N | .
Väide: Ei leidu kahe Turingi masina sogastajat.
Tõestus.
Tõestus rajaneb eeldusel, et on põhimõtteline vahe, kas uurida programmi ainult oraaklipä-
ringute abil (programmi saab ainult nö “küsitleda”, kuid mitte siluda jms) või on programmile
33
(ükskõik kui sogastatud) füüsiline juurdepääs – rakendada programmile teisi programme, uu-
rida mälupöördusmustrit jne. See erinevus kaob, kui programm on täielikult õpitav (learnable)
oraaklipäringute kaudu9. Seetõttu kasutame kontranäitena funktsiooni, mis ei ole õpitav. Tões-
tamiseks teeme vastuväitelise eelduse, et eksisteerib definitsioonis 4 toodud tingimustele vastav
kahe TM sogastaja O.
Konstrureerime Turingi masina C sõnede α, β ∈ 0, 1k jaoks järgmiselt:
Cα,β(x) =
β x = α
0k muudel juhtudel
See tähendab, et töötades sisendil x, on masina C väljundiks β kui x = α ning 0k vastastel
juhtudel. Siinkohal eeldame, et sisendi x korral töötab masin Cα,β 10 · |x| sammu, kus konstant
10 on vabalt valitud.
Teiseks konstrueerime Turingi masina D, mis äsjakirjeldatud Turingi masina C koodi kasu-
tades suudab vahet teha, kas C arvutab sama funktsiooni mis Cα,β või Cα′,β′ , kus (α,β) 6= (α′,
β′). Seega saame masina:
Dα,β(x) =
1 C(α) = β
0 muudel juhtudel
Kuna võib esineda juhtumeid, kus TM C töötab etteantud sisendi korral väga kaua või ei
peatu üldse, võib selliselt konstrueeritud Turingi masina D puhul osutuda keeruliseks 0-i väljas-
tamine. Seetõttu kasutame tõestuses edaspidi masina Dα,β modifitseeritud varianti, mis töötab
masina C(α) sisendiks andes kO(1) sammu ning väljastab 0, kui C selle jooksul ei peatu. Nii
Cα,β kui ka Dα,β kirjelduse keerukuseks on Θ(k).
Järgnevalt olgu need kaks (sogastatud) Turingi masinat antud vastasele A, kes ründeks ra-
kendab lihtsalt üht masinat teisele – st A(C, D) = D(C). Siinkohal on vajalik sarnaselt Dα,β-
le tehtud modifikatsioonile piirata ka A tööaega (max|C|, |D|)O(1) sammule ning sundida
väljastama 0, kui D selle jooksul ei peatu. Nii saame suvaliste sõnede α, β ∈ 0, 1k korral
võrduse:9Nt programm, mis väljastab ise-enda lähtekoodi.
34
Pr[A(O(Cα,β),O(Dα,β)) = 1
]= 1 . (1)
Paneme tähele, et juhuslike α ja β korral peab oraaklipääsu masinatele Cα,β ja Dα,β omav
algoritm S leidma õige α sisuliselt küsides oraakli väärtusi ükshaaval kõikvõimalike sisendite
korral. Kuna võimalikke väärtusi on 2k ja S töötab polünomiaalses ajas, ei ole õige α leidmine
tõenäolisem kui 2−Ω(k). Seega, konstrueerides Turingi masina Zk, mis väljastab alati 0k ning iga
PPT S korral, saame:
∣∣∣ Pr[SCα,β ,Dα,β(1)k = 1
]− Pr[SZk,Dα,β(1)k = 1
]∣∣∣ ≤ 2−Ω(k) , (2)
kus tõenäosused on võetud üle ühtlase jaotusega α ja β hulgast 0, 1∗ ning S mündivisete10
(coin tosses).
Turingi masina A definitsioonist lähtuvalt saame, et:
Pr[A(O(Zk),O(Dα,β)) = 1
]= 0 . (3)
Võrduste (1), (2) ja (3) kombinatsioon on aga vastuolus eeldusega, et O on kahe Turingi
masina sogastaja.
Tekkinud vastuolu selgitamiseks olgu toodud järgmine näide:
Olgu meil mingi boolean tagastusväärtusega ning 32-bitist täisarvu sisendina kasutav funkt-
sioon A:
bool A(int parameeter)
if(parameeter==123456)
return true;
else
return false;
10 Tegemist on tõenäosusliku algoritmiga, mis võib sisemiselt kasutada juhuarve ehk nö mündiviskeid.
35
Ehk tegemist on lihtsa funktsiooniga, mis tagastab väärtuse tõene, kui sisendiks antav
32-bitine arv võrdub arvuga 123456 ning väär vastasel juhul. Omades ainult oraaklipääsu sel-
lisele funktsioonile, peame me proovima kõiki 32-bitilisi väärtusi teada saamaks, kuidas antud
funktsioon töötab – me ei tea, kas seal on üks või mitu “if”-lauset, millise konstandiga sisendit
võrreldakse jne.
Järgmiseks defineerime teise funktsiooni, mis võtab sisendina viida (pointer) funktsioonile
ning tagastatava väärtuse tüübiks olgu jällegi boolean. Olgu selliseks funktsiooniks B:
bool B(bool (*parameeter)())
return parameeter(123456);
Kutsudes välja funktsiooni B argumendiga A, saame vastuseks tõene. Kui meil on veel üks
A sarnane funktsioon Z, mis erineb A-st ainult kontrollkonstandi poolest, tagastab meile kutsung
B(Z) alati väärtuse väär.
Seega saame, et sarnaselt võrdusele (1) Pr[B(A)=tõene
]= 1 (B tagastab alati väärtu-
se tõene, kui argumendiks anda viit funktsioonile A). Teisest küljest, võrdusele (3) sarnaselt,
saame, et Pr[B(Z)=tõene
]= 0 (B tagastab alati väärtuse väär, kui argumendiks anda viit
mõnele teisele funktsioonile peale A).
Oletame nüüd, et meil ei ole absoluutselt mingit informatsiooni funktsioonide A, B või Z
kohta. Seepärast peame proovima iga võimalikku (32-bitist) sisendit, et õppida nende käitumist
ning teada saada, milliste sisendite puhul nad tegelikult väärtuse tõene väljastavad. Selleks
defineerime funktsiooni oraakliPääs(B,A), mida mõistame kui B kasutamist funktsiooni
A oraaklina (B küsib A-lt, kas antud sisendi puhul saame vastuseks tõene). Kuna A ja Z puhul
on võimalikke erinevaid sisendeid 232 (sisendiks on 32-bitine arv), siis tõenäosus, et juhusliku
täisarvu argumendiks andmisel saame vastuseks tõene, on umbes 2−32. Seega saame:
Pr[oraakliPääs(B,A) = 1
] ≤ 2−32
ja
Pr[oraakliPääs(B,Z) = 1
] ≤ 2−32 .
36
Lahutades esimesest tõenäosusest teise, saame igal juhul absoluutväärtuselt väiksema suuru-
se, kui seda on 1/232. Nii oleme saanud võrdusele (2) sarnaneva tulemuse, mis ütleb, et omades
ainult oraaklipääsu funktsioonidle A ja Z, on õige tõeväärtuse saamise tõenäosus kaduvväike:
∣∣∣ Pr[oraakliPääs(B,A) = 1
]− Pr[oraakliPääs(B,Z) = 1
]∣∣∣ ≤ 2−32 .
Tehes nüüd lahutustehte∣∣∣(1) - (3) -
∣∣(2)∣∣∣∣∣ ehk:
∣∣∣ Pr[B(A) = 1
]− Pr[B(Z) = 1
]− ∣∣ Pr[oraakliPääs(B,A) = 1
]−Pr
[oraakliPääs(B,Z) = 1
]∣∣∣∣∣ ,
kus liikmeid ümber paigutades saame eelnevast väiksema või võrdse avaldise:
∣∣∣ Pr[B(A) = 1
]− Pr[oraakliPääs(B,A) = 1
]− Pr[B(Z) = 1
]−Pr
[oraakliPääs(B,Z) = 1
]∣∣∣ .
Saame tulemuse, mille väärtus on kindlasti suurem kui 1/232, millega oleme saavutanud vastu-
olu, kahe TM sogastaja definitsiooniga.
Pöördume tagasi esialgse arutluskäigu juurde. Nimelt ignoreerisime me ennist fakti, et kär-
bitud sai nii A kui Dα,β tööaeg. Seda tehes peame me jälgima, et võrdused (1) ja (3) kehtima
jääksid. Teeme siinkohal selle võla tagasi.
Võrdus (1) sisaldab endas (a) A(O(Dα,β),O(Cα,β)), mis A definitsiooni kohaselt tähendab
(b)O(Dα,β)(O(Cα,β)) täitmist. Sogastaja definitsioonist (def. 1) tulenevalt on (b)-l sama funkt-
sionaalsus Dα,β(O(Cα,β)), mis omakorda seisneb (c) O(Cα,β)(α)) täitmises. Jällegi näeme, et
sogastaja funktsionaalsuse nõude kohaselt täidab (c) sama funktsiooni, mis Cα,β(α). Sogastaja
definitsiooni polünomiaalse aeglustumise omaduse kohaselt on (c) tööaeg (10k)O(1) = kO(1),
mis tähendab, et ka Dα,β(O(Cα,β)) tööaeg on kO(1). Seega, rakendades veel kord polünomiaalse
aeglustumise omadust, saame, et ka (b) tööaeg on kO(1), mis omakorda viitab sellele, et A töö-
aeg on kO(1). Täpselt sama arutluskäik käib ka võrduse (3) kohta asendades Cα,β Zk-ga. Sellega
oleme näidanud, et Dα,β ja A tööaja piiramine ei mõjutanud võrduste (1) ja (3) kehtivust. ¤
37
4.5 Ühe TM sogastamine
Olles teinud eeltööd kahe Turingi masinaga, oleme valmis näitama, et ei eksisteeri ka ühe Tu-
ringi masina sogastajat. Selleks defineerime esmalt Turingi masinate ja programmide kombi-
natsioonid.
Funktsioonide ja programmide kombineerimine
Funktsioonide, Boole’i skeemide ja TM-te f0, f1 : X → Y korral defineerime nende kom-
binatsiooni f0#f1 : 0, 1 × X → Y järgmiselt – (f0#f1)(b, x)def= fb(x). Vastupidiselt –
kui on ette antud TM (Boole’i skeem) C : 0, 1 × X → Y , võime me skeemist C efektiiv-
selt moodustada kombinatsiooni C0#C1, seades Cb(x)def= C(b, x). Sealjuures C0 ja C1 pikkus
ja tööaeg on põhimõtteliselt võrdne C-ga. Samuti on oraaklipääs kombineeritud funktsioonile
f0#f1 ekvivalentne oraaklipääsuga kummalegi funktsioonile f0, f1 eraldi.
Teoreem 1. Turingi masina sogastajat ei eksisteeri.
Tõestus.
Sarnaselt kahe Turingi masina sogastaja võimatuse tõestamisele eelmises peatükis teeme ka
siin vastuväitelise eelduse, et eksisteerib Turingi masina sogastaja O. Sõnede α, β ∈ 0, 1k
jaoks olgu defineeritud Turingi masinad Cα,β , Dα,β ja Zk, mis on kirjeldatud peatükis 4.4. Neid
omavahel kombineerides saame uued Turingi masinad Fα,β = Cα,β#Dα,β ja Gα,β = Zk#Dα,β .
Ka vastane A on analoogne punktis 4.4 kirjeldatule erinevusega, et A esimeseks sammuks
on etteantud programm osadeks lahutada. St, et saades ette Turingi masina F , lahutab algoritm
A kõigepealt masina F kompositsiooniks F0#F1 ning väljastab seejärel F1(F0). Ka siin tuleb
A-d modifitseerida, et selle tööaeg oleks polünomiaalne (F -st sõltuv).
Olgu meil veel definitsiooni 1 kohaselt leiduv PPT S, mis omab oraaklipääsu Turingi masi-
natele ja Fα,β ja Gα,β . Sarnaselt eelmisele tõestusele saame siis:
Pr[A(O(Fα,β)) = 1
]= 1 (1)
38
∣∣∣ Pr[SFα,β(1)k = 1]− Pr [SGα,β(1)k = 1
]∣∣∣ ≤ 2−Ω(k) (2)
Pr[A(O(Gα,β)) = 1
]= 0 , (3)
kus jällegi tõenäosused on võetud üle ühtlase jaotusega valitud α, β ∈ 0, 1k ning tõenäosus-
like algoritmide A, S-i ja O
Nendest võrdustest tuletame vastuolu Turingi masina sogastaja definitsiooniga. Kasutades
võrdusi (1), (2) ja (3), saame võrratuse:
∣∣∣ Pr[A(O(Fα,β) = 1
]︸ ︷︷ ︸
(a)
−Pr[SFα,β(1)k = 1
]︸ ︷︷ ︸
(b)
−Pr[A(O(Gα,β)) = 1
]︸ ︷︷ ︸
(c)
−
−Pr[SGα,β(1)k = 1
]︸ ︷︷ ︸
(d)
∣∣∣ ≤ 2−Ω(k) .
Võrdusest (3) on teada, et (c) = 0. Turingi masina sogastaja definitsioonist ning faktist, et
S-i puhul on tegemist A-le vastava oraakliga Turingi masinaga, lähtuvalt saame, et (c)− (d) ≤2−Ω(k). Toetudes jällegi tõsiasjale, et S on A-le vastav oraakliga TM, peab kehtima (a)− (b) ≤2−Ω(k). Kuna (a) = 1 vastavalt võrdusele (1), tekib aga vastuolu võrdusega (3), mis nõuab, et ka
(b)− (c) ≤ 2−Ω(k).
Sellega oleme saavutanud vastuolu definitsiooniga 1, mistõttu võime öelda, et Turingi ma-
sina sogastajat ei eksisteeri. ¤
Sarnaselt kahe TM sogastaja võimatuse tõestuses toodud näitele olgu toodud ka siin piltlik
näide:
Olgu meil nö kompositsioonfunktsioon, mis koosneb peatükis 4.4 toodud funktsioonidest
sel viisil, et teine funktsioon on sisse kirjutatud esimesse. Selline, argumendiks ühebitise arvu
0 või 1 võttev boolean tagastustüübiga funktsioon, on näiteks järgmine:
bool C(bool kasutA)
int kntr = 0;
if (kasutA)
kntr = 123456;
39
if (kntr==123456)
return true;
else
return false;
mille vastane võib lammutada osadeks järgmiselt:
bool A(int parameeter)
if (parameeter==123456)
return true;
else
return false;
bool Z(int parameeter)
if (parameeter==0)
return true;
else
return false;
bool B(bool (*parameeter)())
return parameeter(123456);
bool C(bool kasutA)
if (kasutA)
return B(A);
else
return B(Z);
40
Funktsiooni C boolean tüüpi argumendiga välja kutsudes valime alati, kas kutsuda välja B(A)
või B(Z). Siin B(A) tulemuseks on alati tõene – saame tõmmata paralleeli võrdusega (1).
B(Z) väärtuseks alati väär – paralleel võrdusega (3). Oraaklipääsuga neile funktsioonidele on
õnnestumise tõenäosus 1/232, millest lähtuvalt saame (sarnaselt 2 TM tõestuse punktis toodud
näitele) võrdusele (2) vastava tulemuse. Sellega oleme jõudnud kahe TM sogastaja võimatuse
tõestusega analoogse tulemuseni, kuid siin on C puhul tegemist “ühe Turingi masinaga”.
Mõningased raskused kerkivad esile saamaks sama tulemust Boole’i skeemide korral, kuid
nende käsitlemine ja tõestuse toomine jääb antud töö raamest välja.
4.6 Sogastamatute funktsioonide pere
Käesolevas peatükis jõuame sogastamatute funktsioonide pere olemasolu näitamiseni. Vastava-
te teoreemide tõestamiseks läheb vaja järgnevat lemmat:
Lemma 1. Kui eksisteerivad ühesuunalised funktsioonid11, siis iga k ∈ N ja α, β ∈ 0, 1k
korral leidub jaotus Dα,β selliselt, et:
1. Iga D ∈ Supp(Dα,β) on polünomiaalse suurusega Boole’i skeem.
2. Leidub polünomiaalse tööajaga algoritm A suvaliste skeemide C ja D ∈ Supp(Dα,β)
jaoks nii, et AD(C, 1k) = 1 parajasti siis, kui C(α) = β
3. Iga PPT S korral, Pr [SD(1k) = α] = neg(k), kus tõenäosused on võetud üle DR← Dα,β ,
α, βR← 0, 1k ja S mündivisete.
Antud lemma poolt garanteeritud jaotus on teoreetiliseks abivahendiks edasiste teoreemide tões-
tamisel. Jaotuse D täpne sõltuvus parameetritest α ja β ei ole antud juhul oluline – oluline on
teoreemi 2 tõestamise seisukohalt, et ta neist parameetritest võib sõltuda. Siinkohal ei hakka
me tooma lemma tõestuskäiku (see on toodud artiklis [8]) ning eeldame edaspidi lihtsalt, et see
kehtib.
Teoreem 2. Kui eksisteerivad ühesuunalised funktsioonid, ei eksisteeri Boole’i skeemi sogasta-
jat.11 Ühesuunalist funktsiooni kasutatakse tõestuses krüpteerimisskeemi Enc koostamiseks.
41
Tõestus.
Oletame vastuväiteliselt, et eksisteerib Boole’i skeemi sogastaja O. Olgu k ∈ N ja α, β ∈0, 1k korral defineeritud skeemid Zk ja Cα,β , nagu toodud peatükis 4.4 ning jaotus Dα,β vas-
tavalt lemmas 1 toodule. Olgu iga k ∈ N korral üle polünomiaalse suurusega Boole’i skeemide
kaks jaotust:
Fk: kompositsiooni Cα,β#D väljund, kus α ja β on ühtlase jaotusega hulgast 0, 1k ning
DR← Dα,β .
Gk: kompositsiooni Zk#D väljund, kus α ja β on ühtlase jaotusega hulgast 0, 1k ning
DR← Dα,β .
Teisisõnu öeldes – jaotused Fk ja Gk justkui väljastavad juhuslikke skeeme, kusjuures esi-
mese jaotuse väljundi mõlemad komponendid Cα,β ja D on juhuslikud. Juhuslikkus siinkohal
ei tähenda aga seda, et skeemid oleksid tingimata täiesti suvalised, tähendusetud moodustised –
skeem on ka siis juhuslik, kui tema üks detail on juhuslikult valitud.
Olgu A lemma 1 teisele omadusele vastav tõenäosuslik polünomiaalse tööajaga Turingi
masin ning A′ selline PPT, mis lahutab sisendiks antava skeemi F kompositsiooniks F0#F1
ning arvutab AF1(F0, 1k), kus k on skeemi F0 sisendi pikkus. Seega, andes ette Boole’i skeemi
O(Fk), on A′ töö sisuks AD(C, 1k), kus D arvutab sama funktsiooni, mis skeem jaotusestDα,β ,
ning C arvutab sama funktsiooni, mis Cα,β . Lemma 1 teisest omadusest saame:
Pr[A′(O(Fk)) = 1
]= 1 ja Pr
[A′(O(Gk)) = 1
]= 0 .
Nüüd peaks kehtima iga tõenäosusliku algoritm S korral:
∣∣∣ Pr[SFk(1k) = 1
]− Pr[SGk(1k) = 1
]∣∣∣ ≤ 2−Ω(k) ,
mis läheb vastuollu Boole’i skeemi sogastaja definitsiooniga. Oraaklipääsu omamine skeemile
jaotusest Fk (või Gk vastavalt) on võrdväärne oraaklipääsuga skeemidele Cα,β (Zk vastavalt) ja
DR← Dα,β , kus α ja β on ühtlase jaotusega hulgast 0, 1k. Lemma 1 kolmandast omadusest
42
saame, et S-i tõenäosus α päringu edukuseks on kaduvväike, seega ei suuda algoritm S eristada
Boole’i skeemi Cα,β-t skeemist Zk-st. ¤
Teisalt näitame aga järgneva lemmaga, et tõhusa sogastaja leidumise eelduseks on ühesuu-
nalised funktsioonid.
Lemma 2. Kui eksisteerib tõhus sogastaja, siis eksisteerivad ühesuunalised funktsioonid.
Tõestus.
Oletame, et O on efektiivne sogastaja vastavalt definitsioonile 2. Sõnede α ∈ 0, 1k ja
b ∈ 0, 1 jaoks olgu Cα,β : 0, 1k → 0, 1 järgmiselt defineeritud Boole’i skeem:
Cα,β(x)def=
b x = α
0 muudel juhtudel
Nüüd defineerime funktsiooni fk(α, b, r)def= O(Cα,b; r), nt Cα,b sogastamine mündivisete
abil. Teisisõnu, sogastaja O on tõenäosuslik algoritm (TM), mis kasutab juhuarvudena polü-
nomiaalse pikkusega bitistringi. Näitame, et f =⋃
k∈N fk on ühesuunaline funktsioon. Selgelt
on fk arvutatav polünomiaalse aja jooksul. Kuna bitt b on informatsioon, mis teoreetiliselt on
määratud fk(α, b, r) poolt, piisab tõestamiseks, et f on ühesuunaline funktsioon, kui näidata, et
b on f -i tugev bitt (hard-core bit). Selle näitamiseks näeme kõigepealt, et iga PPT S korral:
Prα,b
[SCα,b(1)k = b
] ≤ 1
2+ neg(k) .
O virtuaalse musta kasti omadusest lähtub, et iga PPT A korral:
Prα,b,r
[A(f(α, b, r)) = b
]= Pr
α,b,r
[A(O(Cα,b; r)) = b
] ≤ 1
2+ neg(k) .
Sellega oleme näidanud, et b on funktsiooni f tugev bitt – järelikult f on ühesuunaline funkt-
sioon. ¤
Järeldus. Võime öelda, et ei eksisteeri Boole’i skeemi sogastajat (tingimusteta). Nagu va-
rem mainitud, tähendab see, et ei leidu ka Turingi masina sogastajat.
43
Seega oleme jõudnud hetkeni, mil võime tuua ära tõestuse algul mainitud sogastamatute
funktsioonide pere olemasolu kohta.
Teoreem 3. (sogastamatud funktsioonid) Kui eksisteerivad ühesuunalised funktsioonid, siis ek-
sisteerib sogastamatute funktsioonide pere.
Tõestus.
Olgu Fk ja Gk jaotusfunktsioonid teoreemist 2 ja olgu Hk jaotus, mis tõenäosusega 1/2
väljastab valimi jaotusest Fk ning tõenäosusega 1/2 valimi jaotusest Gk. Väidame, et Hk on
sogastamatute funktsioonide pere.
Sogastaja definitsioonis nõutud Hkk∈N efektiivne arvutatavus on näidatud lemma 1 tões-
tuses. Defineerime predikaadi π(f), mis väljastab 1, kui f ∈ ⋃k Supp(Fk) ning 0 vastasel
juhul. (paneme tähele, et(⋃
k Supp(Fk)) ⋂ ( ⋃
k Supp(Gk))
= ∅ ja seega π(f) = 0 iga
f ∈ ⋃k Supp(Gk).
Teoreemis 2 kirjeldatud vastase A′ korral teame, et π(f) on arvutatav polünomiaalse ajaga
mis tahes funktsiooni f ∈ Supp(Hk) arvutavast Boole’i skeemist. Kuna oraaklipääs Fk-le pole
eristatav oraaklipääsust Gk-st, nagu näidatud teoreemis 2, siis võib öelda, et fR← Hk korral pole
oraaklipääsuga π(f) arvutatavuse tõenäosus oluliselt suurem kui 1/2. Kuna see tõenäosus ei ole
parem juhuslikust arvamisest, oleme näidanud, et Hkk∈N on sogastamatute funktsioonide pere
ning teoreem kehtib. ¤
4.7 Tulemuse tähendus
Pidades silmas eelmises punktis toodud tõestuse tulemust, tuleb edaspidi, rääkides sogastami-
sest, hüljata sogastatud programmi puhul virtuaalse musta kasti omaduse olemasolu võimalik-
kus selle üldlevinud tähenduses. See ei tähenda aga sugugi mitte, et sogastamine täiesti kasutu
või koodi mingil kindlal viisil arusaamatuks tegemine võimatu oleks. Tavaliselt piisab ka vähe-
mast kaitsest kui seda teoreetiliselt pakuks nö ideaalne sogastamine. Sogastamise eesmärgiks
praeguste teadmiste juures on pöördprojekteerimise võimalikult kulukaks tegemine. Nt võib
44
piisata väiksema tähtsusega programmide puhul ainult pöördprojekteerimise keerulisemaks te-
gemisest ning suurema tähtsusega programmide lahtimurdmise aja võimalikult pikaks venita-
misest.
Kõnealune tulemus on ühtaegu nii tugev kui ka nõrk nagu selgitab B. Barak artikli [8]
mitteformaalses lühikokkuvõttes [16]:
• Konkreetse näite abil on tõestatud, et leiduvad sellised programmid/funktsioonid, mille
puhul iga sogastaja töö ebaõnnestub – tähtis pole siinjuures mitte see, et õnnestub peita
mõningast informatsiooni, vaid see, et kui tahes sogastatud koodist on võimalik taastada
esialgne kood.
• Tulemuse nõrkus seisneb asjaolus, et tõestatud on ainult see, et iga sogastaja kukub läbi
mõne programmi puhul – ei ole tõestatud mingite teiste programmide sogastamise eba-
turvalisust ning võib loota, et kaitstavad funktsioonid ei kuulu nö sogastatamatute funkt-
sioonide perre.
B. Barak jt näitasid artikliga [8], et ei ole võimalik eksisteerida sellistel sogastamise tei-
sendustel, mis oleksid universaalselt kasutatavad mis tahes funktsiooni või programmi sogas-
tamisel. Vähemalt tõestuses toodud funktsioonide pere esindajat sisaldava programmi puhul
jääks võimetuks iga sogastaja. See tähendab, et turvalisust tuleb vaadelda iga kasutusjuhu kor-
ral eraldi ning positiivse tulemuse saavutamiseks tuleb spetsifitseerida, mida me tahame üldse
sogastamise abil kaitsta.
Võidakse väita, et peatükis 4 sai refereeritud väga kitsale ja konkreetsele definitsioonile vas-
tava sogastaja võimatus ning sellest tulenevalt võib jääda ka mulje, et saadud tulemus puudutab
vaid väga väikest programmide hulka. Seetõttu võib olla väike lootus, et leidub sogastamise
definitsioon, mille saavutamine ei oleks võimatu, ent oleks rakenduste puhul siiski kasutatav.
Näitamaks, et leidub olukordi ja rakendusi, mille puhul piisavat turvalisust pakkuva sogastaja
definitsiooni ei ole võimalik praktiliselt saavutada, on tõestusele lisaks toodud hulk laiendusi.
45
4.8 Tulemuse laiendused
Näitamaks, et toodud tõestuse puhul ei olnud tegemist vaid ühe definitsiooniga mängimisega
ning illustreerimaks saadud tulemuse praktilist tähendust, laiendati tööd veelgi. Andes ühelt
poolt järele definitsioonide tugevuses, tehti teiselt poolt väikeseid muudatusi varemkasutatud
konstruktsioonides ning välistati koheselt neile definitsioonidele vastava sogastamise saavuta-
mise võimalikkus. Edasiste tõestuste läbiviimiseks on esmalt on ära toodud täielikult sogasta-
matute funktsioonide pere definitsioon.
Nimelt võib funktsioonist f ühe biti arvutamatuks jäämisest väheks jääda (st mõningate ra-
kenduste puhul ei piisa sogastamise ebaturvalisuse näitamiseks, et ainult üks bitt funktsioonist
ei ole taastatav). Selle asemel, et funktsioonist f jääks arvutamatuks ainult π(f), võib nõuda, et
tervet funktsiooni f arvutava Boole’i skeemi taastamine oleks võimatu. Nii viiaksegi, eeldusel,
et eksisteerivad ühesuunalised funktsioonid, selliselt tugevdatud sogastamatute funktsioonide
pere olemasolu tõestus läbi väikese muudatusega – oraaklipääsuga ei ole arvutatav mitte ainult
üks vaid palju bitte.
Üks võimalus, kuidas leida reaalselt saavutatava sogastaja definitsioon, oleks järgi anda so-
gastaja funktsionaalsuses – sogastatud Turingi masin või Boole’i skeem ei pea arvutama täp-
selt sama funktsiooni, mis originaal. Sellest ideest tuleneb ligikaudse sogastaja (approximate
obfuscator) mõiste. Seejuures peab olema täpselt kindlaks määratud, mida me mõistame ligi-
kaudsuse all, kuna meil ei oleks kasu sogastatud Boole’i skeemist, mida ei saa kasutada origi-
naali asemel. Nii pakutakse välja ligikaudsuse määratlus, mis lubab mingi sisendi puhul sogas-
tatud skeemi töö tulemusel erineda sogastamata skeemi tulemusest ainult väga väikese tõenäo-
susega. See tõenäosus võib sõltuda vaid sogastavast algoritmist, mitte aga sisendist. Definitsioo-
ni 3 eeskujul defineeritud tugevalt sogastamatute funktsioonide pere (strongly unobfuscatable
function ensemble) leidumine välistab ka ligikaudse sogastaja võimalikkuse.
Punktis 3.1 sai mainitud, et sogastamise üks võimalikke rakendusi oleks riskivabalt sala-
jasest võtmest avaliku võtme tegemine. Paraku leidub sogastamatu salajase võtme krüpteeri-
misskeem, mis ka selle võimaluse välistab. See tähendab, et ei leidu üldist meetodit, mis lubaks
teha avalikust võtmest salajase ainult krüpteerimisalgoritmi sogastades. Sealjuures on võima-
46
lik murda süsteem täielikult, kui on olemas ligipääs algoritmi realiseerivale Boole’i skeemile.
Tõestatakse, et kui eksisteerib krüpteerimisskeem, siis leidub ka samadele turvanõuetele vastav
sogastamatu krüpteerimisskeem. St mis tahes sogastaja definitsioon, mis oleks piisavalt tugev
muutmaks salajane võti turvaliselt avalikuks võtmeks, oleks võimatu saavutada, kuna leiduvad
sogastamatud krüpteerimisskeemid.
Analoogiliselt konstrueeritakse definitsioonid ja viiakse läbi tõestused ka sogastamatu sig-
natuuri, sõnumi autentimise skeemi ja pseudojuhuslike funktsioonide12 korral. Seega, selliste
programmide sogastatud vormide levitamine on väga ebaturvaline. Siinkohal tuleb märkida, et
tõestatakse, et mitte need rakendused ei ole teostatavad, vaid et ei leidu sellist üldotstarbelist
sogastajat, mille abil neid saaks teostada.
1990ndate aastate lõpul, enne sogastamise võimatuse tõestamist, nägid ilmavalgust mitmed
sogastamist kui pöördprojekteerimise vastast kaitsemeedet käsitlevad heuristilist laadi artiklid.
Üheks produktiivsemaks antud valdkonnas olid Collberg ja tema meeskond, kuid oma sogas-
tamistehnikaid pakkusid välja teisedki. Võimalik, et veidi väiksema entusiasmiga, kuid ikka-
gi sogastamatuse tõestuse tulemusest hoolimata jätkatakse tööd samal teemal edasi. Järgnevas
peatükis on ära toodud peamised sogastamise teisendused ning nende liigitus. Erinevalt käes-
olevast peatükist aga piirdub nende teisenduste efektiivsuse hindamine pigem hindamise, mitte
aga teoreetiliste tõestustega.
12 Pseudojuhuslik funktsioon (pseudorandom function) on O. Goldreich, S. Goldwasseri ja S. Micali poolt tut-
vustatud mõiste. Tegemist on krüptograafias kasutatavate funktsioonidega, mille väljund on eristamatu juhuslikust
väljundist olemata seejuures tegelikult juhuslik.
47
5 Praktiline lähenemine
Kuigi ei saa öelda, et sogastamise puhul ülearu käsitletud teemaga tegemist oleks, leidub siiski
mõningaid sogastamistehnikate kirjeldamist, liigitamist ja rakendamist puudutavaid artikleid.
Mõningatele neist heidetakse ette teoreetiliste aluste puudumist. Samas ei väidagi näiteks artik-
li [13] autorid, et nende toodud teisendused oleksid murdmatud, vaid otse vastupidi – öeldakse,
et programmile füüsilist juurdepääsu omavale vastasele piisavalt aega ja ressursse andes on iga
sogastamine pööratav. Kuna 1997. aastal ei teatud veel midagi sogastamise võimatuse tõestu-
sest, võib arvata, et tegemist oli pigem intuitiivse, kuid siiski tõese väitega.
Selleks, et sogastavaid teisendusi (obfuscating transformation) liigitama ja hindama hakata,
peab esmalt leppima kokku, mida me nende all silmas peame. Sogastav teisendus on defineeri-
tav järgmiselt:
Definitsioon 5. PT→ P ′ on sogastav teisendus, kui:
• T teisendab lähteprogrammi P sogastatud programmiks P ′.
• P -l ja P ′-l on sama märgatav käitumine (observable behavior), välja arvatud juhud, kui
programm ei lõpeta tööd või lõpetab veaga.
• T on mõjus teisendus. See tähendab, et P ′ on arusaamatum kui P .
Märgatava käitumise all mõistame programmi tööd, mis on vaadeldav kasutaja poolt tavali-
ses mõistes – mingi kindla sisendi puhul peab P ′ väljund olema sama mis P -l. Seejuures võib
sogastatud programm oma töö käigus luua ajutisi faile, kirjutada logi vms, kuid need peaksid
kasutaja eest peidetuks jääma. Funktsionaalsusest lähtuvalt on veidi teistsuguse definitsiooni
sogastavale tranformatsioonile andnud C. Wang [24]. Tema käsitluses ei ole oluline mitte es-
malt sisend/väljund käitumine, vaid täidetav ülesanne – kui kaks erinevat realisatsiooni täidavad
sama ülesannet, on nad funktsionaalselt ekvivalentsed, olenemata sisendist/väljundist.
Artiklis [13] toodud sogastamistehnikate jaotus on olnud lähtematerjaliks paljudele edasis-
tele artiklitele ja teesidele. Ka alltoodud sogastamistehnikate liigitus on toodud esmajärjekorras
nimetatud artiklile toetudes.
48
5.1 Sogastamistehnikate liigitus
Lähtudes masinkoodi sogastamisest, on oma nägemuse sogastamistehnikate liigitusest välja
pakkunud G. Wroblewski [23]. Teistsugust lähenemist võib kohata C. Wangi doktoritöös [24]
ja kindlasti on erinevaid võimalusi liigitamiseks veelgi, kuid esimeseks ja vast kõige enam tsi-
teeritud artikliks sel teemal on C. Collbergi jt “A Taxonomy of Obfuscating Transformations”
[13]. Selle eeskujul liigitatakse erinevad sogastamistehnikad sogastamise objektiks oleva infor-
matsiooni olemuse järgi kolme järgnevasse klassi:
• Vorminguline sogastamine (layout obfuscation);
• Käsuvoo sogastamine (control-flow obfuscation);
• Andmesogastamine (data obfuscation).
Lisaks neile võib tegelikult neljandana välja tuua põhimõtteliselt täiesti teistsugused – takista-
vad (preventive) teisendused, mille eesmärgiks on pöördsogastaja töö võimalikult raskeks tege-
mine. Kõiki toodud sogastamistehnikaid jagatakse veel omakorda selle järgi, milliseid operat-
sioone nad läbi viivad ning nendest lähemalt juba järgnevates peatükkides.
5.1.1 Vorminguline sogastamine
Nagu nimigi viitab, sogastatakse sel viisil esmajoones programmikoodi (nii lähte- kui ka bi-
naarkoodi) vormingut. Eemaldatakse kommentaarid, võimalik, et taanded, tühjad read jm koodi
lugemist hõlbustavad nähtused. Tegemist on kõige lihtsamini realiseeritavate teisendustega, mis
ühelt poolt ei põhjusta mingeid lisakulutusi ressurssidele, kuid on teisalt suhteliselt väikese
mõjususega. Samuti käib vormingulise sogastamise alla protseduuride inlining ja outlining13,
millest esimene tähendab protseduuri väljakutsumise asendamist kutsutava protseduuri keha
endaga ning teise puhul võidakse suvaline osa koodist teha eraldi protseduuriks. Lisaks sogas-
tamisele toob inlining endaga kaasa ka koodi optimeerimist, seda eriti väikeste ja tihti väljakut-
sutavate protseduuride korral.
Vormingulise sogastamise alla kuulub ka leksikaalne sogastamine (lexical obfuscation), mis
sisaldab endas koodis leiduvate identifikaatorite (muutujate, protseduuride jm) nimede šifree-
rimist (scrambling) ründajale arusaamatule kujule, et varjata nende mõtet ja otstarvet. Näiteks13 Tegelikult kuuluvad inlining ja outlining nii vormingulise kui käsuvoo sogastamise alla.
49
võib esialgsest selgetähenduslikust protseduuri nimest arvutaPalk saada mitte midagi ütlev
lskj3f. Kuigi tegemist on ühesuunalise funktsiooniga (teisendatud nimest ei ole võimalik tu-
letada esialgset), mis muudab pöördprojekteerimise veidi raskemaks, ei takista see motiveeritud
ründajat siiski teada saamast identifikaatorite tegelikku otstarvet.
Kuna tegemist on suhteliselt lihtsate ja loomulike teisendustega, mille efektiivsuses kahelda
võib, on ehk sellega seletatav ka vormingulise sogastamise vähene käsitletus akadeemilises
kirjanduses.
5.1.2 Käsuvoo sogastamine
Enamus käsuvoo ja mõned andmesogastamise teisendused põhinevad läbipaistmatutel predi-
kaatidel (opaque predicate). Mitteformaalselt lahti seletades nimetatakse predikaati läbipaist-
matuks, kui tema väärtus on teada sogastajale, ent on pöördsogastajale (deobfuscator) raske
avastada. Selliste predikaatide abil on võimalik protseduuri käsuvoog katki teha suvalisest ko-
hast. Me kirjutame P T (P F ), kui läbipaistmatu predikaadi P väärtuseks on alati tõene (väär)
ning P ?, kui P väärtus võib olla nii tõene kui väär (Joonis 1)14.
Joonis 1. Läbipaistmatu predikaadi abil käsuvoo muutmine.
Katkendjoon tähistab teed, mida kunagi ei kasutata ning pidev
joon teed, mida võidakse kasutada.
Sogastavate teisenduste kvaliteet sõltub peaasjalikult kasutatavate läbipaistmatute predikaa-
tide kvaliteedist. Triviaalseteks nimetatakse selliseid predikaate, mille väärtuse suudab pöörd-
sogastaja leida lokaalse staatilise analüüsi käigus – st uurides vaid üht käsuvoo graafi põhi-
blokki. Arusaadavalt ei ole sellistest predikaatidest erilist kasu. Lisaks pöördsogastajale ei tohi
ka kompilaatorile läbipaistmatu predikaadi väärtus ilmne olla, kuna vastasel juhul eemaldab iga
14 See ja järgnevad joonised pärinevad artiklist [13].
50
korralik kompilaator selle optimeerimise käigus. Automaatsetele pöördsogastajatele vastupida-
vate konstruktsioonide loomine on käsuvoo sogastamise seisukohast esmase tähtsusega. Selliste
predikaatide loomise detailidel peatutakse lähemalt artiklis [14].
Käsuvoo sogastamise liigid
Käsuvoo sogastamise eesmärgiks on erinevate tehnikatega käsuvoo tegelikust käitumisest
arusaamise võimalikult raskeks tegemine, kuid kõik meetodid langevad ühte kolmest kategoo-
riast [13]:
• Käsuvoo koondamises seisnevad teisendused (control-flow aggregation);
• Käsuvoo arvutamise abil läbiviidavad teisendused (control-flow computation);
• Käsuvoo järjestuse muutmises seisnevad teisendused (control-flow ordering).
Käsuvoo koondamise teisendused
Käsuvoo koondamise teisendustest võib välja tuua inliningu, outliningu, vahelehestamise
(interleaving) ja kloonimise (cloning), mis kõik seisnevad peaasjalikult algselt loogiliselt kok-
kukuulunud koodi (meetodi) laialilõhkumises või tegelikult omavahel seostamatute segmentide
ühte meetodisse kokkupanemises.
Inlining ja outlining, mõisted, millele raske eestikeelset vastet leida, said põgusalt tutvusta-
tud juba eespool. Lisaks sellele, et inlining’u puhul on tegemist tõhusa optimeerimistehnikaga,
kujutab ta endast ka väga vastupidavat sogastamistehnikat, kuna peale väljakutsutava koha asen-
damist kutsutava protseduuri kehaga, protseduur ise koodist eemaldatakse. Outlining on mõnes
mõttes vastupidine protsess inlining’ule – protseduure mitte ei eemaldata, vaid neid luuakse
juurde. Nende kahe tehnoloogia olemust edastab ilmekalt joonis 2.
Sarnaselt eelmisele kahele tehnoloogiale ei ole ilmselt eriti tuntud või ilmne ka vahelehes-
tamise mõiste. Hoolimata keerulisest nimetusest on aga selle idee suhteliselt lihtne – omavahel
51
Joonis 2. Inlining ja outlining
liidetakse kokku kahe meetodi kehad ja nende parameetrite listid ning lisatakse meetodite va-
helist liiklust kontrolliv parameeter – st parameeter, mille abil kontrollitakse, kumba meetodit
taheti rakendada (Joonis 3). Ka siin on oluline, et omavahel liidetavad meetodid oma olemuselt
sarnased oleksid, kuna täiesti erinevate meetodite sulandamisel tehtud teisendus võib ilmselt
pöördprojekteerijas kahtlust äratada.
Joonis 3. Meetodite vahelehestamine. Tegemaks vahet, kas suunata kontroll meetodi M1
või M2 kätte, kasutatakse läbipaistmatut muutujat V .
Lisaks meetodite deklaratsioonide ja kehade uurimisele on pöördprojekteerimisel tähtis ka
uurida keskkonda, kust meetodid välja kutsutakse. Selle raskendamise võimaluseks on meeto-
dite kloonimine – ühest meetodist erinevate teisenduste abil mitmete koopiate tegemine ning
programmi töö jooksul erinevate isendite kasutamine (joonis 4).
52
Joonis 4. Meetodite kloonimine. Klassi C1 kuuluv meetod m1 ja klassi C2 kuuluv meetod
m on saadud esialgsest klassi C kuuluvast meetodist m erinevate sogastatavate teisenduste
abil. x.m(5) ja x.m1(7) kutsuvad välja näiliselt erinevad, kuid käitumiselt identsed
meetodid. Klassi C1 kuuluvat meetodit m aga ei kutsuta kunagi välja.
Käsuvoo arvutuslikud teisendused
Arvutuslikud (computational) käsuvoo teisendused jaotatakse kolme kategooriasse:
1. Õige käsuvoo peitmine tegelikult ebaoluliste lausete abil (predikaadid, mis on alati väärad
või tõesed. Nt 7x2 − 1 6= y2, mille väärtuseks on alati tõene [15]).
2. Sellise objektkoodi lisamine, millele ei vasta tegelikku kõrgema taseme keele konstrukt-
siooni.
3. Võlts vookontrollide lisamine.
Esimesse kategooriasse kuuluvad näiteks ebavajalikku või surnud15 (dead) koodi lisavad
teisendused, mis on hõlpsasti teostatavad varemtutvustatud läbipaistmatute predikaatide abil.
Näiteks on toodud joonisel 5 mõned võimalused, kuidas näiliselt katkestada käsuvoo graafi
blokki S = S1 . . . Sn. Joonisel 5(a) on lõhutud blokk S kaheks väiksemaks blokiks predikaadi
P T abil. Kuna antud predikaadi väärtuseks on alati tõene, jääb tegelikult arvutuskäik samaks.
15 Surnud koodi all peame arusaadavalt silmas koodisegmenti, mis on programmis olemas, kuid mille täitmiseni
kunagi ei jõuta.
53
Joonis 5. Harude loomine läbipaistmatute predikaatide abil.
5(b) tutvustab võimalust käsuvoogu näiliselt muuta predikaadi P ? abil. Olenemata valitud teest,
järgneb predikaadi väärtuse leidmisele sisuliselt ikkagi alati esialgse bloki S täitmine pooleli-
jäänud kohast, kuna f(Si) = f(Sai ) = f(Sb
i ). Kolmas võimalus (5(c)) on nö kompositsioon esi-
mesest ja teisest näitest – sarnaselt teisele võimalusele luuakse erinevate teisenduste abil kaks
haru, mis tegelikult sama ülesannet täidavad, kuid esimesele näitele analoogselt üheni neist ku-
nagi järg ei jõua. Sarnaselt on võimalik teha keerulisemaks ka näiteks “for”- ja “while”-lausete
lõpetamistingimustest arusaamine.
Tarkvara on võimalik sogastada, luues madalama taseme keele konstruktsioone, millele ei
leidu kõrgema taseme keele otsest vastet – seda juhul, kui kompileerimise tulemusena saadav
masin- või virtuaalmasinkood on programmeerimiskeelest väljendusrikkam. Näiteks leidub ja-
va baitkoodis käsk goto, kuid programmeerimiskeeles endas sellist käsku ei ole. Nii on näiteks
alati kindla väärtusega läbipaistmatut predikaati kasutades võimalik muuta käsuvoogu käsuga
goto kuhugi “hüpates”. Kuigi tegelikkuses kunagi selle käsuni ei jõuta, jääb siinkohal java
pöördsogastaja hätta – kuna programmeerimiskeeles sellist käsku ei ole, luuakse mingi läheda-
ne kuid vigane vaste või loobutakse üldse. Formaalsemalt öeldakse sel puhul, et java objektkoo-
dis on võimalik esitada käsuvoo graafi, mis ei ole redutseeritav (reducible) java koodiks.
Väidetavalt üks efektiivsemaid ja samas kulukamaid sogastavaid tranformatsioone on koodi
tõlkimine (table interpretation), mis seisneb valitud koodisegmendi konverteerimises mingi-
54
le teisele programmerimiskeelele vastavaks (virtuaal)masinkoodiks. Muudetud koodisegmendi
täitmise eest hoolitseb edaspidi sogastatud programmi lisatud vastav interpretaator. Arusaada-
valt võib parema sogastatuse saavutamiseks ühe programmi puhul kasutada mitmeid erinevaid
keeli, kuid siin seab piirangud vajalike ressursside tohutu kasv. Seetõttu on mõttekas koodi tõl-
kimise abil kaitsta väikeseid või suurt turvalisust nõudvaid koodijuppe.
Nii mõnelgi juhul on sogastavate teisenduste rakendamisel ära kasutatud hoopis teiseots-
tarbeliste tehnikate omadusi (nt inlining). Üheks selliseks on ka arvutuste paralleliseerimine –
meetod mitmeprotsessorilisel arvutil töötava programmi töö optimeerimiseks. Sogastamisena
kasutatava paralleliseerimise puhul ei ole aga taotletavaks eesmärgiks mitte programmi efek-
tiivsemaks tegemine, vaid käsuvoo sogastamine.
Paralleliseerimiseks on kaks võimalust:
• Sisuliselt tühja tööd tegevate protseduuride loomine.
• Tegelikult järjestikku täidetavate tööde paralleelselt täitmine.
On selge, et mõlemad võimalused toovad endaga kaasa lisakulutusi ressurssidele, kui neid
rakendada üheprotsessorilisel arvutil kasutatava programmi sogastamiseks. Kui nö paralleelselt
jooksvatel protseduuridel ei ole ühiselt jagatavaid andmeid, on nende koos jooksutamine suhte-
liselt lihtsalt teostatav (joonis 6). Teatud andmeid omavahel jagavate protseduuride puhul tuleb
nende paralleelse täitmise korral tupikute vältimiseks kasutada sünkroniseerimisprimitiivide abi
(joonis 7). Paralleliseerimisega kaasnevaid lisakulutusi õigustab selle tehnika mõjusus ning hea
vastupidavus staatilisele analüüsile.
Joonis 6. Arvutuste paralleliseerimine, kui puuduvad jagatavad andmed.
55
Joonis 7: Arvutuste paralleliseerimine jagatavate andmete korral.
Käsuvoo järjestuse teisendused
Programmeerijatel on üldiselt tavaks loogiliselt ühtekuuluv informatsioon lähtekoodis ühte
kohta kokku koondada. Kuigi sageli ei ole see otseselt vajalik, teeb see nii koodi kirjutamise,
lugemise kui ka koodist arusaamise kergemaks. Samamoodi nagu koodi loogiliselt paigutatud
andmed hõlbustavad programmeerijal (või mõnel muul isikul, kellel selleks vajadus ja õigus
on) koodist aru saada, võib see olla ka kergendavaks faktoriks pöördprojekteerijale.
Kuigi järjestus, kuidas midagi deklareeritakse või arvutusi läbi viiakse, programmi töö sei-
sukohalt mingit tähtsust ei pruugi omada, võib üsna kindlalt väita, et mida lähemal kaks asja
üksteisele programmikoodis on, seda suurema tõenäosusega on nende vahel mingi seos. Selleks,
et vastasele mitte nii kergelt paljastada koodis leiduvaid seoseid, on käsuvoo järjestuse teisen-
dused, mis seisnevad blokkide, avaldiste, deklaratsioonide jms järjestuse muutmises, säilitades
seejuures sõltuvusseosed. Kuigi selliste muudatustega ei lisata väga palju segasust, ei ole nende
tegemine kulukas ja on tihti ühesuunaline.
Siinkohal tuleb meeles pidada, et kõigi eelpool toodud käsuvoogu muutvate teisendustega
kaasnevad alati mõningased lisakulutused ressurssidele. Seepärast ei tohi nendega üle pinguta-
da, vaid tuleb leida kompromiss hästi sogastatud ja efektiivse programmi vahel.
56
5.1.3 Andmesogastamine
Andmete sogastamise peamiseks eesmärgiks on programmi andmeväljade otstarbest ja kasuta-
misest arusaamise võimalikult raskeks tegemine.
Siia alla kuuluvad teisendused võib oma olemuselt jagada kolmeks vastavalt sellele, milles
andmete muutmine seisneb:
• Andmete salvestamises (storing) ja kodeerimises (encoding) seisnevad teisendused.
• Andmete koondamises (aggregating) seisnevad teisendused.
• Andmete järjestamises (ordering) seisnevad teisendused.
Andmete salvestamine ja kodeerimine
Paljudel juhtudel on programmis kasutatavate andmete salvestamise viis triviaalne (nt loen-
duriks on reeglina mingi positiivne täisarv), mis hõlbustab vastasel nende otstarbest arusaamist.
Kuna mõeldamatu oleks juba programmeerimise käigus võimalikku pöördprojekteerimist kar-
tes keerukaid andmesalvestamise tehnikaid rakendada, võiks siinkohal olla abi sogastamisest.
Salvestus- ja kodeerimisteisenduste eesmärgiks ongi kasutada ebatavalisi andmete salvestus-
või kodeerimisviise, et vältida andmete otstarbe liigset läbinähtavust.
Mitmeid erinevaid selliseid sogastavaid teisendusi leidub muutujatega manipuleerimiseks.
Näiteks on joonisel 8 toodud näide, kuidas muutujast i tehakse i′ = c1 ·i+c2, kus c1 ja c2 võivad
olla mingid vabalt valitud konstandid (antud näites vastavalt 8 ja 3). Seejuures tuleb muidugi
ümber defineerida nii kontrolltingimused kui ka teisendatud muutujal tehtavad aritmeetilised
operatsioonid. Paraku on joonisel 8 toodud näide pöördsogastajale kergesti avastatav.
Ebatavaliste salvestus- ja kodeerimisteisenduste alla käib ka muutujatele kõrgema järgu
andmine (promote variable) – näiteks täisarvu deklareerimine objektina, millel on defineeri-
tud palju keerulisemad meetodid kui ainult liitmine või korrutamine (joonis 9). Kui võime olla
kindlad, et kaks meetodit ei tööta samaaegselt (ja kaasatud ei ole lõimesid), võime muuta mõne
neile meetoditele kuuluvatest lokaalsetest muutujatest globaalseks ning kasutada neid mõlemas
meetodis ühiselt, muutes sel viisil muutuja eluiga (joonis 10).
57
Joonis 8. Muutujate ebatavaline kodeerimine.
Joonis 9. Muutujale kõrgema järgu omistamine.
Joonis 10. Muutuja elueaga manipuleerimine.
Järgmiseks ebatavaliseks kodeerimisviisiks on muutujate poolitamine kaheks või enamaks
teist tüüpi muutujaks. Siinjuures on nii teisenduse efektiivsus, vastupidavus kui ka kulukus ot-
seses sõltuvuses kasutatavate muutujate arvust, mistõttu tuleb leida kompromiss nende vahel
ehk teisisõnu – tükeldamisega ei tohi liiale minna ning piisab vaid kahest-kolmest tükist.
Mingi muutuja V tüübist T tükeldamiseks muutujateks p ja q tüübist U läheb meil vaja:
1. funktsiooni f(p, q), mis seab p ja q väärtused vastavusse muutuja V väärtusega.
2. funktsiooni g(V ), mis seab muutuja V väärtuse vastavusse muutujate p ja q väärtustega.
58
3. p ja q puhul defineeritud operatsioonide abil loodud uusi operatsioone, mis vastaksid tüü-
bil T tehtavatele operatsioonidele.
Sel viisil kodeeringu muutmise lihtsaimaks näiteks on mingi boolean väärtuse esitamine
kahe või enama täisarvu abil.
Staatilised andmed (nt sõned) võivad endas sisaldada vastase jaoks palju pragmaatilist in-
formatsiooni. Üheks võimaluseks taolist leket vähendada on staatiliste andmete protseduurseks
muutmine – näiteks lihtsa sõne deklareerimise asemel moodustame seda sõnet esitava protse-
duuri. Nii on võimalik String s = “sõne”; deklareerimise asemel moodustada järgnev
meetod, kus str on näiteks mingi globaalselt deklareeritud esialgselt tühi string:
void sogStr()
str = str + "s";
str = str + "õ";
str = str + "n";
str = str + "e";
Loomulikult on toodud näide liiga triviaalne ning pöördprojekteerijale kergesti arusaadav, et
oleks mõttekas kasutada seda reaalselt, kuid annab edasi teisenduse mõtte. Reaalselt efektiivse
sogastamisena kasutamiseks tuleks konstrueerida vähem läbipaistvaid meetodeid.
Andmete koondamine
Objekt-orienteeritud keelte puhul (need on ka keeled, mille puhul sogastamisest kõige enam
kasu loodetakse) on keskne roll kanda andmestruktuuridel. Seetõttu on pöördprojekteerija es-
maseks huviks nende taastamine ning loogiliselt võttes ka sogastaja peamiseks eesmärgiks nen-
de peitmine. Vältimaks andmestruktuuride pöördprojekteerimist, on objekt-orienteeritud keelte
puhul võimalikud kahesugused koondamisteisendused – massiivide ja objektide koondamine.
Näiteks on võimalik kahe või enama skalaarmuutuja koondamine ühte muutujasse eeldusel,
et nad sinna ära mahuvad – nii on võimalik kahe 32-bitise arvu koondamine ühte 64-bitisesse
59
muutujasse. Paraku on sellise teisenduse efektiivsus väike, kuna uurides uuel muutujal tehtavaid
aritmeetilisi operatsioone, on kerge vaevaga tuvastatav, et tegelikult sisaldab antud muutuja en-
das kahte arvu. Sellest nõrkusest ülesaamiseks on koodi võimalik lisada võltstehteid, mis ei oma
mingit mõtet uude muutujasse peidetud üksikutel väärtustel opereerides.
Oluliselt rohkem võimalusi võib koondavate teisenduste nime alla liigitada massiivide kor-
ral. Näiteks on joonisel 11 toodud võimalused, kuidas poolitada (split) üks massiiv mitmeks
(laused 1 ja 2), liita (merge) mitu massiivi omavahel (laused 3-5), suurendada (fold) massiivi
dimensoonide arvu (laused 6 ja 7) või nende arvu hoopiski vähendada (flatten) (laused 8 ja 9).
Joonis 11. Massiivide koondamisteisendused.
Kõrgematasemeliste keelte puhul on lisaks eelpool nimetatud koondamistehnikatele võima-
lik liita kaks suvalist klassi kokku või teha üks klass kaheks omavahel pärilussidemes olevaks
klassiks. Klassi keerukus kasvab tema otseste alamate arvu ning päriluspuu juurest suureneva
kauguse kasvuga. Lisaks võib juhtuda, et mitme väikese klassi liitmine üheks suureks annab
võidu jõudluses, kuna ühe suure klassi laadimine võib võtta vähem aega.
60
Andmete järjestuse muutmine
Nagu käsuvoo sogastamise juures korra juba mainitud sai, on nii arvutuste läbiviimise kui
muutujate deklareerimise järjestuses mõningast pragmaatilist informatsiooni. Sellest tulenevalt
võib eeldada, et nii arvutuste kui andmete esitamise järjestuse muutmises peitub sogastamise
teisendus. Järjestamise teisenduste alla kuuluvad suhteliselt lihtsad ning üheselt mõistetavad
muutujate, meetodite, masiiivide jms kõikvõimalikud ümberpaigutamised.
Lisaks nimetatutele on võimalik teha ümberpaigutusi ka massiivi sees, kasutades järjestu-
se muutmiseks läbipaistmatut funktsiooni f(i), mis seab i-ndale elemendile algses massiivis
vastavusse selle elemendi järjekorranumbri uues massiivis (joonis 12). Järjestuse muutmises
seisnevate teisenduste puhul on üldiselt tegemist ühesuunaliste ja vastupidavate, kuid mitte eriti
mõjusate teisendustega.
Joonis 12. Massiivi elementide järjekorra muutmine.
5.1.4 Lisavõimalused
Võime olla üpris kindlad, et tarkvara, mis on piisavalt tähtis, et seda sogastamise abil kaits-
ta, siiski pöördprojekteerida tahetakse. Selleks püütakse tehtud teisendusi automaatse pöördso-
gastaja abil avastada ning kõrvaldada. Pöördsogastaja eesmärgiks on leida programmist sinna
lisatud ebavajalikku koodi otsides läbipaistmatuid predikaate. Automaatse vahendi töö rasken-
damiseks on olemas nö takistavad (preventive) teisendused, mis erinevad oluliselt varemtoodud
teisendustest ühe omaduse poolest: nende eesmärgiks ei ole mitte inimese, vaid masina eksitee-
le viimine.
Takistavaid teisendusi on kahesuguseid – levinud pöördsogastamise tehnikate vastased ning
konkreetsete pöördsogastajate teadaolevatele nõrkustele suunatud teisendused. Takistavate tei-
61
senduste loomisel on abi esmajoones olemasolevate pöördkompilaatorite ja pöördsogastajate
töö (ja nõrkuste) uurimisest. Kõigi siia kategooriasse liigitatavate teisenduste eesmärgiks on
peaasjalikult teiste sogastamistehnikate efektiivsemaks ehk automaatsele ründele vastupidava-
maks muutmine.
5.2 Sogastamise vastaseid ründeid
Käesolev peatükk on omamoodi (loogiliseks) jätkuks eelmisele, sogastamise lisavõimalusi tut-
vustanud alapunktile, kuna lisaks erinevate rünnete loetlemisele, on siin käsitletud ka neile või-
malikke vastumeetmeid. Olenemata rakendatavatest kaitsemeetmetest, võime olla üpris kindlad,
et neid püütakse ikkagi eemaldada. Seepärast tuleb juba programmi sogastades mõelda võima-
like rünnete ehk pöördsogastamise teisenduste peale.
Pöördsogastamise läbiviimiseks vajalikud programmi analüüsimeetodid võib oma olemuselt
jagada staatilisteks ning dünaamilisteks. Staatiline analüüs võimaldab uurida kõikvõimalikke
programmi täitmisviise, sisendeid ja töö jooksul valitavaid teid ning seega taastada programmi
käsuvoo graaf. Meetmeid, kuidas programm staatilisele analüüsile vastupidavamaks teha, pakub
C. Wangi jt artikkel [25]. Dünaamilise analüüsi korral ei uurita otseselt programmi koodi, vaid
jooksutatakse programmi keskkonnas, mis lubab vaadelda ja salvestada programmi töö käigus
tekkivaid väärtusi, süsteemikutseid, andmetevahelisi seoseid jne. Dünaamilise analüüsi abil on
jälgitav programmi tegelik käitumine – siin ei sega uurimist sogastamise abil lisatud kood.
Enamiku sogastavate teisenduste sisuks on tegelikult “õige” koodi peitmine lisatava “võlts-
koodi” abil. Olenemata sellest, kas kasutatakse programmi staatilist või dünaamilist analüüsi, on
pöördsogastaja eesmärgiks programmi lihtsustamine, eemaldades sealt kasutut käsu- ja andme-
voogu. Kuna ka vastasele on teada, et paljud sogastavad teisendused teostatakse läbipaistmatute
predikaatide abil, on (loodava) pöördsogastaja esmaseks ülesandeks nende identifitseerimine
ning väärtustamine.
Sogastamise käigus tehtud muudatusi on võimalik avastada näiteks sogastaja dekompileeri-
mise või sogastatud koodi vaatlemise tulemusena silmahakkavate ning sogastamisele viitavate
mustrite (patterns) leidmise abil. Leides mingi mustri, on juba üpris lihtne luua pöördsogastaja,
62
mis sellele mustrile vastavat sogastatud koodi tuvastab ning eemaldab. Seetõttu ei ole eriti efek-
tiivne kasutada nö valmis või laialt levinud läbipaistmatuid predikaate. Samuti teeb sogastamise
vastupidavamaks sogastatavas programmis endas kasutatavatele konstruktsioonidele sarnaneva-
te predikaatide kasutamine.
Sogastamise tulemusena peidetakse tegelik kood võltskoodi abil, lõhutakse abstraktsioonid
ning puistatakse laiali loogiliselt kokkukuuluvad koodisegmendid. Omavahel kokkukuuluvate
koodilõikude leidmiseks on tükeldamise (slicing) tehnoloogia, mis programmi jälle väiksema-
teks, paremini hallatavateks, ent mingis kindlas mõttes terviklikeks osadeks teevad. Program-
mi tükeldamisele vastupidavamaks tegemisel kasutatakse aliaste lisamist ning muutujate vahel
fiktiivsete sõltuvusseoste tekitamist. Samasse mälupessa viitavad aliased aeglustavad tükeldaja
tööd või põhjustavad ebatäpsete tükkide moodustumise. Fiktiivsete sõltuvusseoste programmi
sisestamine võib oluliselt aeglustada automaatse tükeldaja tööd ning sundida seda tegema suuri
ning seega raskesti hallatavaid lõike.
Statistiline analüüs sisaldab endas predikaatide täitmisaegse väärtuse uurimist. Kui stati-
list analüüsi teostav pöördsogastaja leiab alati tõese või alati väära väärtusega predikaadi,
võib ta ilmselt kahtlustada, et tegemist on sogastamise tulemusena lisatud võltskoodiga. Vaa-
tamata sellele, et kahtlusalune predikaat võib olla näiliselt alati ühesuguse tõeväärtusega, ei
saa seda siiski nii lihtsalt kõrvaldada, kuna tegemist võib olla väga harva teist väärtust võtva
predikaadiga. Selleks, et seda kindlaks teha, kasutatakse järgmist viisi: tehakse programmi mo-
difikatsioon, eemaldades kahtlane predikaat, ning uuritakse, kas modifitseeritud ning esialgne
programm käituvad kõikvõimalike sisendite korral sarnaselt. Jaatava vastuse korral on teada, et
predikaadi võib turvaliselt eemaldada. Kuigi kõikvõimalike teede leidmine on raske, on sel viisil
siiski võimalik edu saavutada. Statilise analüüsi petmiseks tuleks predikaatide P T ja P F asemel
kasutada predikaati P ? või kasutada mitme predikaadi üheaegset murdmist nõudvat skeemi.
5.3 Sogastamise efektiivsus
Igal sogastamistehnikal on oma head ja halvad küljed. Artiklis [13] pakutakse välja kolm ja
artiklis [14] lisatakse neljas näitaja, mille abil on võimalik hinnata erinevate sogastamisteisen-
duste efektiivsust:
63
• Mõjusus (potency). Kõige lihtsamini väljendades hinnatakse mõjususe abil sogastamisega
kaasnevat selgusetust ja koodist arusaamise raskust ehk teisisõnu – sogastava teisenduse
kasulikkust. Sogastamise mõjususe skaalaks on 〈madal, keskmine, korge〉.
• Vastupidavus (resilience). Vastupidavusega mõõdetakse tööd, mis kulub ühelt poolt prog-
rammerijal ning teiselt poolt automaatsel pöördsogastajal sogastava teisenduse avastami-
seks ning kõrvaldamiseks. Teisendus on mõjus, kui sellega suudetakse segadusse ajada
inimene, ning vastupidav, kui seda ei suuda murda automaatne vahend. Vastupidavust
mõõdetakse skaalal triviaalsest kuni uhesuunalisuseni.
• Kulukus (cost). Paljude teisendustega kaasnevad lisakulutused ressurssidele (välja arva-
tud nt kommentaaride eemaldamine jms). Kulukus hindabki sogastamisega kaasneva aja-
kulu, koodi mahu suurenemist, mälukasutust jne. Enamasti ei kaasne teisenduste tegemi-
sega üleminekut ühest keerukuse klassist teise – nt klassist O(n) klassi O(n2). Kulukust
hinnatakse skaalal 〈tasuta, odav, kulukas, kallis〉.
• Läbipaistvus (stealth). Läbipaistvusega hinnatakse sogastatud koodifragmendi ühilduvust
muu koodiga. St, kui hästi või halvasti on sogastatud kood eristatav sogastamata koodist.
Mida raskemini on sogastatud kood märgatav, seda raskem on ka kasutusele võtta vastu-
meetmeid. Teisenduse läbipaistvus sõltub suuresti kontekstist – ühes kohas nähtamatuks
jääv predikaat võib teises kohas vägagi hästi silma torgata.
Nende näitajate puhul on tegemist tarkvaratehnikast pärit keerukuse hindamisel kasutatavate
kriteeriumide mugandustega. Lisaks ülalpool refereeritud kirjeldustele on artiklites [13] ja [23]
toodud ka formaalsed definitsioonid ning konkreetsed valemid vastavate suuruste arvutamiseks.
Kirjeldatud näitajad on nii empiirilistel uuringutel aga ka puhtalt spekulatiivsetel alustel loodud
mõõdupuud, mis hindavad programmi sogastatust, analüüsides lähtekoodi, sogastajale antavaid
parameetreid (nt muutuja tükeldamisel loodavate tükkide arv jms) ning sogastamise tulemusena
saadavat koodi.
Sellised hindamismeetodid on parimal juhul head algoritmide tõhususte võrdlemisel, kuid
jäävad ilmselt hätta konkreetse algoritmi tõhususe mõõtmisega. Seda ennekõike seepärast, et
nimetatud analüütiliste meetodite korral on raske adekvaatselt hinnata inimmõistuse rolli. Inim-
mõistuse võimetele suudab lähedasema hinnangu anda empiiriline analüüs. Nii kasutas näiteks
64
G. Wroblewski oma doktoritöös tutvustatud masinkoodi sogastamise efektiivsuse hindamiseks
tudengite, tarkvara arendajate ning kräkkerite (crackers) abi, lastes neil proovida sogastatud
programme pöördprojekteerida. Tegemist on küll statistiliste andmetega, kuid sellegipoolest
annavad nad sogastamise efektiivsuse hindamisel täpsust juurde.
5.4 Sogastamise alternatiive
Erinevatel põhjustel võib sogastamine tarkvarakaitseks sobimatuks või soovimatuks osutuda.
Kuna enamasti siiski tarkvara kaitsta tahetakse, tuleb sel puhul kasutada alternatiivseid vahen-
deid. Esimeses peatükis käsitletud meetmetele võib panna süüks nende kontsentreeritust piraat-
koopiate tegemise vältimisele, jättes vastasele vabad käed pöördprojekteerimiseks. Järgnevalt
on toodud mõned sogastamise alternatiivid – meetmed peaasjalikult pöördprojekteerimise vas-
tu.
Kõige kindlam viis oma tarkvara kaitsmiseks on seda üldse mitte levitada, vaid müüa ser-
veril töötava programmi poolt pakutavat teenust. Välistades füüsilise juurdepääsu koodile, on
välistatud nii võimalus pöördprojekteerimiseks kui ka piraatkoopiate tegemiseks. Antud lahen-
duse negatiivseks küljeks on võrgu läbilaskevõimest sõltuv viiteaeg ning sellest tulenevad eba-
meeldivused.
Sogastamise teiseks alternatiiviks oleks tarkvara levitamine ning kasutamine krüpteeritud
kujul. Tegemist on üsna populaarse lahendusega, kuid selline meetod suudab täieliku turva-
lisuse garanteerida vaid juhul, kui kogu krüpteerimise ja dekrüpteerimise protsess leiab aset
riistvara tasemel (nt esimeses peatükis mainitud tarkvara-riistvara paketti kasutades). Vastasel
juhul on ründajal alati võimalik protsessidesse sekkuda ning dekrüpteeritud koodi dekompilee-
rida.
Selle asemel, et levitada tarkvara arhitektuurist sõltumatu ning palju metainfot sisaldava
virtuaalmasinkoodi näol, võib olla turvalisem levitada seda masinkoodis, mille pöördprojek-
teerimine on oluliselt raskem (kuigi mitte võimatu). Sellise lahenduse kasutamiseks on vajalik
tarkvara valmiskompileerimine tuntumate arhitektuuride ja operatsioonisüsteemide jaoks. Nagu
iga hea asjaga, kaasneb ka selle meetodiga oma halb külg – risk, et koodi võib olla modifitsee-
65
ritud kurjade kavatsustega kolmanda isiku poolt. Seepärast peab tarkvara looja pakkuma või-
maluse koodi autentimiseks – see tähendab looma kliendile võimaluse identifitseerimaks koodi
autorit ning tuvastamaks, kas koodi on peale publitseerimist muudetud.
66
6 Sogastamise käsitlus peale võimatuse tõestust
Tõestust 100%-list turvalisust tagava sogastaja võimatusest võib pidada antud valdkonnas mur-
ranguliseks, kuna sellega arvestavad enamal või vähemal määral kõik edasised sogastamise-
teemalised tööd. Lähenemisi on sealjuures erinevaid – kas on ideaalse sogastamise võimatus
lihtsalt mainitud, on püütud leida kontranäitega koheselt vastuollu mitte minevat lahendust või
on hoopiski deklareeritud, et nii tugevat turvalisust sogastamiselt ei taotletagi. Nii või teisiti
luuakse endiselt äriotstarbelisi sogastajaid ning avaldatakse sogastamist käsitlevaid heuristilisi
ja vähem heuristilisi töid.
2002. aastal nägi ilmavalgust poolaka G. Wroblewski doktoritöö [23] masinkoodi sogasta-
mise tehnoloogiast, mida autor nimetab üldiseks sogastamismeetodiks, kuna see ei sõltu arhi-
tektuuri spetsiifilistest omadustest ning on vähese vaevaga rakendatav suvalisel arhitektuuril.
Oma töös püstitas Wroblewski hüpoteesid, et masinkoodi sogastamine on kergem kõrgetaseme-
liste keelte sogastamisest, ning et sellise algoritmi efektiivsus ei jää alla seniloodud algoritmide
efektiivsusele. Nende väidete tõestuseks lõi ta masinkoodi sogastamise algoritmi, mille tõhu-
sust analüütiliste ning empiiriliste meetoditega uurides jõudis järeldusele, et loodud meetod on
lihtne, kergelt porditav (portable), paindlik ning vastupidav.
Vastupidiselt eelnevalt mainitud madala taseme koodi sogastamisele on artiklis [26] mindud
hoopis teises suunas – pakutakse välja objekt-orienteeritud keeles loodud programmi disaini
sogastamise tehnikaid. Väites, et seniloodud sogastamistehnikad keskenduvad vaid muutujate
nimede, lokaalse käsuvoo jms primitiivsele peitmisele, pakutakse disaini kui olulise informat-
siooniallika sogastamiseks klasside liitmise, lõhkumise ja objektide tüüpide peitmise tranfor-
matsioone. Artiklis lähtutakse seisukohast, et [8] poolt välistatud ideaalset sogastatust pole va-
jagi ning ainsaks eesmärgiks on teha pöördprojekteerimine majanduslikult otstarbetuks, mitte
aga võimatuks. Erinevalt varasemalt toodud näidetest ei oma need sogastavad teisendused mär-
kimisväärset mõju tööajale ning mõningatel juhtudel on täheldatud isegi jõudluse kasvu.
Sageli kasutatakse tarkvaras leiduva tundliku informatsiooni varjamiseks krüpteerimist. Pro-
grammi funktsioneerimiseks ehk krüpteeritud info dekrüpteerimiseks vajaliku võtme peitmisel
tarkvarasse nähakse võimaliku lahendusena sogastamist. AES ja DES krüptoalgoritmide võtme
67
peitmise tehnoloogiat tutvustavad artiklid [19] ja [20]. Nende tööde puhul on lähtutud seisu-
kohast, et digitaalse omandikaitse (Digital Rights Management) korral on õigem end kaitsta
mitte musta vaid valge kasti ründe eest. Sellega antakse vastasele suurem vabadus (juurdepääs
nii krüpteeritud tarkvarale kui ka keskkonnale, kus see töötab) ning astutakse samm reaalsele
olukorrale lähemale. Erinevalt tavapärasest krüptograafilisest lähenemisest ei otsita neis töödes
sogastamiselt ideaalset kaitset või pikaajalist garantiid, vaid praktilise ning mõistliku tasemega
kaitset rakendustele, mis peaks vastu valge kasti rünnakutele.
Justkui kinnitamaks, et ülalmainitud tehnoloogiate rakendamisel ei ole eesmärgiks saavuta-
da rünnete eest igavest garantiid, näidati koheselt artiklis [18], et DES algoritmi võtme peitmise
tehnoloogiat kasutava tippklassi äriotstarbelise sogastaja puhul leidub ikkagi nõrkusi. Nimelt
on salajane võti koodist leitav ilma kasutatud sogastamise mehhanisme uurimata – sisestades
(sogastatud) programmi töökeskkonda tahtlikult vigu ning jälgides, kuidas programmi töö tea-
tud vigade korral ebaõnnestub. Sellest tulenevalt jõuti järeldusele, et praegused tehnoloogiad on
teatud rünnete korral salajase võtme peitmiseks endiselt ebapiisavad.
Oma negatiivset suhtumist sogastamisse kui turvalisse tarkvarakaitse meetmesse väljendab
A. W. Appel artiklis “Deobfuscation is in NP” [17], kus ta jõuab järeldusele, et pöördsogasta-
mine on NP-kerge16. Kuigi see teadmine ei vii meid koheselt efektiivsete pöördsogastajateni,
on see artikli autori meelest sogastamise jaoks murettekitav tõik, öeldes:“Kontrastiks paljudele
programmianalüüsi meetoditele, mis on lahendamatud, leides, et sogastamine ei ole mitte ainult
lahenduv, vaid ka peaaegu et praktilises haardeulatuses, kitsenevad turvalisuse piirid.”
Suhteliselt negatiivse tulemuseni jõudsid ka artikli [22] autorid, kelle esmaseks eesmärgiks
oli ise-ennast kaitsevate mobiilsete agentide (self-protecting mobile agents) loomine. Luues va-
hendit, mille abil oleks võimalik muuta mobiilne agent ennast kaitsvaks agendiks, jõudsid au-
torid veendumusele, et sogastamise abil piisavat turvalisust pakkuda võimalik ei ole. Seetõttu
sai esialgsest sogastaja loomise projektist lihtsalt sogastamise uurimise projekt. Esialgse plaani
16 Keerukusteoorias nimetatakse NP-kergeks probleemide hulka, mis on lahenduvad polünomiaalses ajas de-
termineeritud Turingi masina poolt, mis kasutab mingi NP-sse kuuluva otsustusülesande lahendamiseks oraaklit.
NP on ülesannete klass, mille lahendite õigsust saab kontrollida sisendi suuruse suhtes polünomiaalse tööajaga
algoritmi abil.
68
käigus rakendatud sogastamistehnikate efektiivsuse katsetamiseks loodi pöördsogastaja, millel
õnnestus üllatava kergusega tehtud teisendused avastada. Töö tulemusena tehti järeldus, et so-
gastamise efektiivseks kasutamiseks tuleb kitsendada rakenduste klassi ning vaja on täiesti uut
lähenemist.
Väidetavalt esimesed positiivsed tulemused sogastamisest formaalselt tõestatud turvalisuse
seisukohast on kajastatud artiklis [21]. Ka selles artiklis on loomulikult aktsepteeritud fakti, et
üldotstarbelist sogastajat ei leidu. Sellest lähtuvalt on uuritavat valdkonda kitsendatud ning kä-
sitletud juurdepääsu kontrolli (access control) sogastamist. Sarnaselt artiklile [8] on sogastami-
ne defineeritud musta kasti abil ning näidatakse, et juhusliku oraakli mudelist17 (random oracle
model) lähtudes on võimalik juurdepääsu mehhanismi sogastada. Autorid ütlevad, et nende tööd
võib ka vaadelda kui esimesi edukaid samme lõplike automaatide ja regulaaravaldiste sogasta-
mise suunas, mis ei ole [8] tulemuse poolt välistatud. Väljapakutud meetodile heidetakse ette
nende liigrasket rakendatavust igapäevaselt kirjutatavates programmides.
17 Juhuslik oraakel on sisuliselt üks juhuslikult valitud funktsioon R : 0, 1∗ → 0, 1, mis seab igale lõplikule
bitistringile vastavusse 0 või 1. Tõenäosusmõõt on defineeritud nii, et iga n ∈ N korral oleks ahend Rn : 0, 1n →0, 1 ühtlase jaotusega. Võib ka öelda, et see on kõigile programmidele kättesaadav (üks ja sama) juhuarvude
allikas, kuid mis sama argumendi teistkordsel esitamisel ei genereeri uut juhuarvu, vaid kasutab sama.
69
7 Edasised arengusuunad
Olles ühelt poolt tutvunud ideaalse sogastamise võimatuse tõestusega ning teiselt poolt näinud
siiski sogastamise erinevaid rakendusi ja ka positiivseid tulemusi, on selge vaid üks – lõplike
järelduste tegemiseks vajab sogastamine veel põhjalikku uurimist. Vaatamata nö negatiivsete-
le tulemustele kõnealuses valdkonnas, leian, et sogastamist turvaliste tarkvarakaitse meetmete
hulgast välja arvata on liialt ennatlik.
Hetkel kannatab sogastamine korrektse definitsiooni puudumise all. Täpsemalt: ei leidu ül-
dist definitsiooni, mis oleks praktiliselt teostatav ning samas 4ndas peatükis toodud tõestuse
tulemusega mitte vastollu minev. Sellise (praktiliselt kasuliku) definitsiooni leidmine tundub
olevat üsna raske, mistõttu oleks edaspidi mõistlik lahendusi otsida kitsamates valdkondades.
Teisest küljest oleks vaja usaldusväärset meetodit sogastamise efektiivsuse hindamiseks.
Selleks, et veenduda sogastamise turvalisuses, on vaja usutavamaid tõestusi ning paremaid
mõõtmisvahendeid kui hindamine mõneti meelevaldsete kriteeriumide alusel – programm võib
olla hea sogastaja peatükis 5.3 toodud näitajate alusel, kuid sellegipoolest mingis osas täielikult
läbi kukkuda.
70
8 Summary
SOFTWARE OBFUSCATION
Jarno Raid
Every year, software industry loses tens of billions of US dollars worldwide to software
piracy. As more and more people have come to depend on computer software, the piracy issue
desperately needs more attention. In this thesis, widespread defense mechanisms against piracy
and possible solutions for protecting intellectual property are briefly covered. The main goal of
the present work is to analyze theoretical boundaries and to introduce practical implementations
of the defense mechanism against reverse engineering – software obfuscation.
Present thesis is divided into four logical parts. First, a brief overview of the essence of
software piracy and its’ various forms is given. Most common legislative means of software
protection as well as a subset of technical methods – hardware assisted software protection are
introduced. Also main properties of software-based intellectual property protection methods,
watermarking and integrity checking, are covered in the first part of the thesis.
Next two chapters (3 and 4) explain the nature of obfuscation and review the article [8], in
which Barak et al. has proven that one hundred percent efficient obfuscation is impossible. The
main result of the article, where obfuscated program was defined as a virtual black-box, was the
proof of the existence of unobfuscatable family of functions. Some more complicated aspects
of the proof are explained in detail and a few illustrations from the “real life” are brought. A
description of how this result was extended and what it really means in practice is given.
To show that obfuscation is not useless, despite the impossibility result of [8], the third
part of thesis concerns the practical use of obfuscation. In section 5 the taxonomy of obfusca-
ting transformations is brought. Some metrics for measuring different properties of obfuscating
transformations and some possible alternatives to obfuscation are presented.
Last two chapters concern further studies of obfuscation as the fourth logical part of the
thesis. The obfuscation impossibility result by Barak et al. was a breakthrough – all subsequent
71
publications dealing with obfuscation have taken the proof more or less into consideration.
Chapter 6 reviews some of the articles on obfuscation that have been published since 2001.
Some of them have been neutral towards obfuscation as a secure way of software protection,
some have taken more negative stand. In the year of 2004 a paper that claimed to be the first
one, that showed positive results of obfuscation in the sense of provable security, was published.
The conclusion of the present work is that there are still many open problems in the field
of obfuscation. Although there are many opinions of obfuscation that contradict each other, one
thing is clear – a proper definition for obfuscation is needed. A definition, which would provide
sufficient security to be on one hand useable in practice and not impossible to meet on the other
hand. For positive results and effectiveness, the class of applications should be restricted and
proper metrics for measuring the efficiency of obfuscation should be invented.
72
9 Kasutatud kirjandus
Viited
[1] “Autoriõiguse seadus”. Vastu võetud Riigikogus 11. novembril 2004. a. RTI, 2004, 77,
527. https://www.riigiteataja.ee/ert/act.jsp?id=810714.
[2] “Patendiseadus”. Vastu võetud Riigikogus 16. märtsil 1994. a. RT I 1994, 25, 406.
https://www.riigiteataja.ee/ert/act.jsp?id=730956.
[3] Global Software Piracy Study, http://www.bsa.org/globalstudy/, 2004.
[4] O. Goldreich, R. Ostrovsky, “Software Protection and Simulation on Oblivious RAMs”.
JACM, Vol. 43, No. 3, pp. 431-473, 1996.
[5] A. B. Kahng, J. Lach, W. H. Mangione-Smith, S. Mantik, I. L. Markov, M. Potkonjak,
P. Tucker, H. Wang, G. Wolfe, “Watermarking Techniques for Intellectual Property Protec-
tion”. 35th ACM/IEEE Design Automation Conference Proceedings, pp. 776-781, 1998.
[6] H. Chang, M. J. Atallah, “Protecting Software Codes By Guards”. In Proc. Second ACM
Workshop Digital Rights Management (DRM), pp. 160-175, 2002.
[7] B. Horne, L. Matheson, C. Sheehan, R. E. Tarjan, “Dynamic Self-Checking Techniques
for Improved Tamper Resistance”. In Proc. 1st ACM Workshop on Digital Rights Manage-
ment (DRM 2001), pp. 141-159, 2001.
[8] B. Barak, O. Goldreich, R. Impagliazzo, S. Rudich, A. Sahai, S. Vadhan, K. Yang, “On
the (Im)possibility of Obfusating Programs”. In Proc. CRYPTO 2001, 2001.
[9] J. Nagra, C. Thomborson, C. Collberg, “Software Watermarking: Protective Termino-
logy”. In Australasian Computer Science Conference, pp. 177-186, 2002.
[10] C. Thomborson, C. Collberg, “Watermarking, Tamperproofing and Obfuscation - Tools
for Software Protection”. In IEEE Transactions on Software Engineering, volume 28, pp.
735-746, 2002.
73
[11] C. Thomborson, C. Collberg, “Software Watermarking: Models and Dynamic Em-
beddings”. In Proceedings of Symposium on Principles of Programming Languages,
POPL’99, pp. 311-324, 1999.
[12] R. Venkatesan, V. Vazirani, S. Sinha, “A Graph Theoretic Approach to Software Water-
marking”. In Proc. 4th International Information Hiding Workshop, Pittsburgh, PA, pp.
157-168, 2001.
[13] C. Thomborson, C. Collberg, D. Low, “A Taxonomy of Obfuscating Transormations”.
Technical Report 148, Dept. of Computer Science, University of Auckland, 1997.
[14] C. Thomborson, C. Collberg, D. Low, “Manufacturing Cheap, Resilient and Stealthy
Opaque Constructs”. In POPL ’98: The 25th Annual ACM SIGPLANSIGACT Sympo-
sium on Principles of Programming Languages, pp. 184-196, 1998.
[15] C. Thomborson, C. Collberg, D. Low, “Breaking Abstractions and Unstructuring Data
Structures”. In Proc. 1998 IEEE International Conference on Computer Languages, pp.
28-38, 1997.
[16] B. Barak, “Can We Obfuscate Programs?”. Http://www.math.ias.edu/∼boaz/Papers/
obf_informal.html.
[17] A. Appel, “Deobfuscation is in NP.”. Http://www.cs.princeton.edu/∼appel/papers/
deobfus.pdf, 2002.
[18] M. Jacob, D. Boneh, E. Felten, “Attacking an Obfuscated Cipher by Injecting Faults”.
In Proc. 2nd ACM Workshop on Digital Rights Management (DRM 2002), pp. 16-31.
Springer LNCS 2696, 2003.
[19] S. Chow, P. Eisen, H. Johnson, P. C. Oorschot, “White-Box Cryptography and an AES
Implementation”. In Proc. 9th International Workshop on Selected Areas in Cryptography
(SAC 2002), pp. 250-270. Springer LNCS 2595, 2003.
[20] S. Chow, P. Eisen, H. Johnson, P. C. Oorschot, “A White-Box DES Implementation for
DRM Applications”. In Proc. 2nd ACM Workshop on Digital Rights Management (DRM
2002), pp. 1-15. Springer LNCS 2696, 2003.
74
[21] B. Lynn, M. Prabhakaran, A. Sahai, “Positive Results and Techniques for Obfuscation”.
Advances in Cryptology - EUROCRYPT 2004, Lecture Notes in Computer Science, Vol.
3027, pp. 20-39, 2004.
[22] B. Lynn, B. Matt, A. Reisse, T. v. Vleck, S. Schwab, P. LeBlanck, “Self-Protecting Mobile
Agents Obfuscation Report”. Technical Report #03-015, Network Associates Labs, 2003.
[23] G. Wroblewski, “General Method of Program Obfuscation”. PhD Dissertation, Wroclaw
University of Technology, Institute of Engineering Cybernetics, Poland, 2002.
[24] C. Wang, “A Security Architecture for Survivability Mechanisms”, PhD Dis-
sertation, University of Virginia, School of Engineering and Applied Science,
http://www.cs.virginia.edu/survive/pub/wangthesis.pdf, 2000.
[25] C. Wang, J. Hill, J. Knight, J. Davidson, “Software Tamper Resistance: Obstructing Static
Analysis of Programs”, Technical Report CS-2000-12, Department of Computer Science,
University of Virginia, 2000.
[26] M. Sosonkin, G. Naumovich, N. Memon, “Obfuscation of Design Intent in Object Orien-
ted Applications”. In Proc. ACM Workshop on Digital Rights Management, 2003.
75