Paralelní (skoro)SHA

Napsali jste někdy opravdu příšerný zdroják, write-only špagetu a strašlivou, zcela neportabilní odpornost? Že by vás ani nenapadlo se tím chlubit? Hm. Ale já mám naštěstí prima výmluvu.

Máme ve škole takový zajímavý předmět. Jmenuje se Algoritmy a jejich implementace, letos byl vyučován poprvé a jeho náplň byla vskutku zajímavá a různorodá. MJ a Pasky se totiž pokoušeli o nemožné: Během semestru nás učili céčko pořádně (v prvních třech přednáškách se probíraly zajímavé části svaté knihy C99, časem došlo i na rozšíření gcc). Strávili spoustu času vyvracením toho, co nás učili na Principech, OZD a podobných přednáškách a ukazovali, jak je to doopravdy. Povídali nám o cachích, pamětích, procesorech (pozvali Honzu Hubičku ochotného podělit se o všechno, na co nepodepsal NDA). Učili jsme se, jak při programování znalost těchto věcí používat. Dozvěděli jsme se třeba, jak rychle třídit, nebo jak se počítá na grafických kartách.

Požadavkem ke zkoušce je aplikovat nabyté znalosti a napsat s jejich využitím něco zajímavého. Dlouho jsem si lámala hlavu, co by to mělo být: Všechna ta třídění, stromy či násobení matic sice skýtají spousty prostoru pro optimalizace, ale je to poněkud fádní. Nakonec jsem přece jen zavadila o nápad, který se mi zalíbil: Co takhle zkusit si spočítat SHA paralelně?

Tedy, spočítat SHA paralelně samozřejmě ve skutečnosti nejde. Můžeme ale udělat obezličku: Rozdělit si vstup na bloky, spočítat paralelně hashe bloků a hashe těchto hashů vydávat jako výsledek. Pokud umíme SSE, můžeme navíc místo jednoho hashe bloku počítat rovnou čtyři proložené naráz, výsledek zahashovat a dál postupovat jako v minulém případě.

Což zní zatraceně jednoduše. Přesto to nakonec vydalo na pár večerů zábavy: Nejprve zamotat se do pavučiny vlastních vláken (hmm, takové věci se opravdu dají psát buď jednoduše nebo blbě... nebo oboje), potom věštit z kávové sedliny (pardon, ze souboru emmintrin.h), vymýšlet, jak to slepit, aby to bylo aspoň trochu efektivní, přijít na to, proč to funguje jen jako poněkud pomalý generátor náhodných čísel, a proč to dává jiné výsledky než referenční implementace SHA1 (fakt pěkně blbě se to debuguje). Prostě, přestože to vypadá jako maličkost, jeden na tom naloví mnohem víc expů, než by čekal. Opravdu, schválně si něco takového zkuste napsat taky.

Výsledek splnil očekávání - na mém quadu (ha, konečně můžu zaměstnat nějakým vlastním výtvorem všechna jádra) to běží tak devětkrát rychleji než normální shasum. Ostatně, pokud máte mašinku, co umí SSE, má 32bitové inty a gcc, můžete si to vyzkoušet.

A pokud náhodou zrovna taky studujete na matfyzu, nejste hackeři, co mají x86 a spol. mašinky v malíčku a chcete s tím aspoň trochu něco dělat, nezapomeňte si příští zimu zapsat předmět Algoritmy a jejich implementace.

Toto je reklamní článek předmětu NDMI074 :-)

Re: Paralelní (skoro)SHA maertien (24. 2. 2009 - 2:42) Sbalit(3)
Zdrojak vypada pekne brutalne, smekam ;-)
Jinak zkusil jsem to a toto jsou vysledky:


blanka:/tmp/pssesha# cat /proc/cpuinfo | ./pssesha
3540239338231c43d3f468e41ac7bc28f2026b67
blanka:/tmp/pssesha# cat /proc/cpuinfo | sha1sum
d3b70f98dc540aa2c9e01d09a0e7759e5d3a8e31 -

Je to spravne? Nemelo by to hodit stejny vysledek jako sha1sum. /proc/cpuinfo se samozrejme behem tech par vterin, nez jsem to zadal, nezmenil. Jinak preju dobrou noc, ja jdu spat.
Re: Paralelní (skoro)SHA anicka (24. 2. 2009 - 10:02) Sbalit(2)
> Je to spravne? Nemelo by to hodit stejny vysledek jako sha1sum.
> /proc/cpuinfo se samozrejme behem tech par vterin, nez jsem to zadal,
> nezmenil. Jinak preju dobrou noc, ja jdu spat.

Noo... kdyz si prectes ten clanek (nebo README) jeste jednou, mozna si
vsimnes, ze pisu, ze normalni SHA1 (tedy to, co pocita shasum) paralelne
napsat nejde (pouziva totiz vysledky ziskane pri hashovani minuleho
bloku). Ja tedy pocitam neco malicko jineho - tak, abych na tom byla
uplne stejne, pokud jde o bezpecnost, ale aby to zaroven mohlo bezet
paralelne. Pri kontrole hashu od stazenych cedecek Ti to tedy
neposlouzi. Pokud si budes neco hashovat sam, bude Ti jedno, cim (kdyz
to bude dost bezpecne) a budes to chtit mit rychle, muze se Ti to ale
hodit.

A v cem je to jine nez SHA1? Zjednodusene receno, normalni SHA1 vzdy
vezme blok, prozene jej osmdesati koly ruznych bitovych operaci a
prohazeni, dostane hash, tim inicializuje nejake promenne pro vypocet
hashe dalsiho bloku... a na konci na velikost bloku zarovna vypadovanim
nulami plus velikosti puvodnich dat.

Moje paralelni sseckove SHA pouziva na praci s jednim blokem presne tu
samou transformaci jako SHA1 (tady jsem se tedy potrebovala s SHA1 jeste
shodnout na vysledku, abych se mohla tvarit, ze je to stejne bezpecne),
ovsem tady podobnost konci: Transformacni funkce ve skutecnosti pracuje
nad ctyrikrat vetsim blokem (vypadovanym jen nulami), ktery zpracovava
prolozene a dostane z nej ctyri hashe (a pokazde se nad nim znovu
inicializuje). Z techto ctyr hashu a velikosti bloku (nahrada za SHA1
padding) spocita normalni SHA1 z knihovny a ulozi ho. Kdyz jsou takto
zpracovany vsechny bloky, z vyslednych hashu se spocita SHA1 z knihovny,
a to je vysledek.

Je uz jasne, proc to nutne musi pocitat neco jineho, a proc to z hlediska
bezpecnosti vyjde nastejno?

Re: Paralelní (skoro)SHA maertien (24. 2. 2009 - 13:00) Sbalit(1)
Jasny. Pokud to pocita hashe hashu, tak to nutne musi hazet neco jineho, kdyz hashujes sha hashe. Preci jen jsem to cetl az v noci, takze jsem nebyl tak pozorny. Znas to ;-)
Re: Paralelní (skoro)SHA xxx (4. 3. 2009 - 15:45) Sbalit(5)
Hm, a preco by to malo byt rovnako bezpecne ako SHA? Je na to nejaky dobry dovod?
Re: Paralelní (skoro)SHA mj (5. 3. 2009 - 11:38) Sbalit(4)
Je. SHA1 je iterativní hashovací funkce, takže její bezpečnost se opírá
o bezpečnost kompresní funkce (zjednodušeně: to je funkce, která vezme
dva bloky dat a zahashuje je do jednoho bloku). Aniččin program používá
tutéž kompresní funkci, jen do ní efektivně posílá data v jiném pořadí,
než klasická SHA1. Kdyby tedy v tomto programu byla nějaká slabina,
bude tato slabina existovat i v SHA1 pro trochu zpermutovaný vstup.

Re: Paralelní (skoro)SHA xxx (5. 3. 2009 - 16:37) Sbalit(3)
Nejde mi do hlavy, preco potom nie je tak navrhnuta aj povodna SHA? Bolo by fajn, keby bola paralelizovatelna pri rovnakej bezpecnosti, nie? :)
Re: Paralelní (skoro)SHA mj (5. 3. 2009 - 16:56) Sbalit(2)
Ja bych rekl, ze proste proto, ze v dobe, kdy SHA1 vznikala (1993), jeste lide
moc o paralelismu nepremysleli.

Re: Paralelní (skoro)SHA anicka (7. 3. 2009 - 10:14) Sbalit(1)
> Ja bych rekl, ze proste proto, ze v dobe, kdy SHA1 vznikala (1993),
> jeste lide moc o paralelismu nepremysleli.

Uvazime-li, ze ta vec je stara vic nez patnact let, a neco, na cem
clovek vyuzije paralelismus je bezne mit doma tak nejvys posledni tri, ani
nestrelili zas tak moc vedle. Nez se to rozsiri poradne, SHA1 skonci
tam, co MD5 a bude jedno, ze to nikdy neumela - verim v Klimu :-)

A nakonec ani vystacit si s konstantnim mnozstvim pameti nemusi byt
vzdycky k zahozeni. Ono je to vzdycky neco za neco.

Re: Paralelní (skoro)SHA af (21. 6. 2009 - 14:29) Sbalit(1)