KryptoCore-Entwurf und Funktionale Programmierung Tobias Häberlein und Matthias Brettschneider [email protected] [email protected] Hochschule Albstadt-Sigmaringen Studiengang Kommunikations- und Softwaretechnik Tübingen, 13.03.09 T. Häberlein, M. Brettschneider () KryptoCore-Entwurf Tübingen, 13.03.09 1 / 23 Übersicht 1 Funktionale HDLs 2 Haskell Crash Kurs 3 ForSyDe Crash Kurs 4 MD5 in ForSyDe 5 MD6 in Haskell 6 Literatur T. Häberlein, M. Brettschneider () KryptoCore-Entwurf Tübingen, 13.03.09 2 / 23 Funktionale HDLs Warum funktionale Programmierung? 1 (rein) Funktionale Programme sind zustandsfrei I I I Der Programmierer schreibt die Befehlsreihenfolge nicht vor. Nebenläufigkeit braucht nicht speziell modelliert zu werden, sondern ist implizit da. Referentielle Transparenz 2 Funktions-Komposition ' Schaltkreis-Komposition 3 Funktionen höherer Ordnung ' Schaltkreis-Strukturen 4 Lazy infinite lists ' Stream-Modelling 5 Typsysteme (insb. Haskell’s) sind ausdrucksstärker. T. Häberlein, M. Brettschneider () KryptoCore-Entwurf Tübingen, 13.03.09 3 / 23 Funktionale HDLs Stand der Technik Existierende Funktionale HDLs Hydra (Haskell-DSEL) Lava (Haskell-DSEL) ForSyDe (Haskell-DSEL) [Sander et al, 2004] Cryptol (Haskell-artig; parametrisch getypt) [Cryptol, 2008] Viele weitere I I I I SAFL (Statically Allocated Functional Language) Reflect (Reflexive Programmiersprache; entwickelt bei Intel 2003 [O’Leary et al, 2006]) HML (ML-DSEL) MyHDL (Python-DSEL) Problem: . . . die meisten Ansätze sind nicht “industrial-strength” T. Häberlein, M. Brettschneider () KryptoCore-Entwurf Tübingen, 13.03.09 4 / 23 Funktionale HDLs Unsere MERSES Forschungs-Mission Modellierung von CryptoCores . . . Da Krypto-Anwendungen sehr algorithmisch . . . ” . . . besser abstrakter modellieren. ⇒ HW/SW Co-Design hier besonders sinnvoll. . . . mit funktionalen HDLs Funktionale SW-Sprachen abstrakter (als Prozedurale) ⇒ Funktionale HW-Sprachen abstrakter (als Prozedurale) Ziel: Verwendung / Weiterentwicklung von 1 2 ForSyDe Cryptol T. Häberlein, M. Brettschneider () KryptoCore-Entwurf Tübingen, 13.03.09 5 / 23 Haskell Crash Kurs Typen und Funktionen ∧ Funktionsapplikation = Leerzeichen double :: Int → Int double x = x ∗ x Jede Funktion hat einen (statischen) Typ (+) :: Int → Int → Int T. Häberlein, M. Brettschneider () KryptoCore-Entwurf Tübingen, 13.03.09 6 / 23 Haskell Crash Kurs Funktionen höherer Ordnung . . . sind Funktionen, die als Parameter Funktionen erwarten und / oder als Rückgabewert Funktionen liefern, das Mittel, um Programme zu kombinieren. Bsp: Funktionskomposition (.) :: (b → c) → (a → b) → (a → c) (.) f g x = f (g x) T. Häberlein, M. Brettschneider () KryptoCore-Entwurf Tübingen, 13.03.09 7 / 23 Haskell Crash Kurs Listen . . . die wichtigste Datenstruktur der Funktionalen Programmierung. Einige wichtige Listenfunktionen head :: [a] → a tail :: [a] → [a] reverse :: [a] → [a] T. Häberlein, M. Brettschneider () KryptoCore-Entwurf Tübingen, 13.03.09 8 / 23 Haskell Crash Kurs Iteration: map und fold Funktionale Sprachen kennen keine Schleifen Stattdessen: Funktionen höherer Ordung: map . . . wendet eine Funktion auf eine Liste von Werten an. map :: (a → b) → [a] → [b] Bsp: map (+2) [3, 10, 12] ergibt [5, 12, 14] fold . . . kombiniert Elemente einer Liste mit beliebiger Operation fold :: (b → a → b) → b → [a] → b Bsp: fold ⊕ e [e0 , . . . , en ] T. Häberlein, M. Brettschneider () ergibt (· · · ((e ⊕ e0 ) ⊕ e1 ) ⊕ . . . en ) KryptoCore-Entwurf Tübingen, 13.03.09 9 / 23 ForSyDe Crash Kurs ForSyDe’s Algebra (1) Ein Prozess bildet Signale (=unendliche Liste von Werten) auf Signale ab: Prozess Bausteine process → | | | | | | zipSY unzipSY mapSY procFun1 delaySY procFun1 zipWithSY procFun2 zipWith3SY procFun3 ... ProcFun = “normale” Haskell-Funktion mit AST-Infos. T. Häberlein, M. Brettschneider () KryptoCore-Entwurf Tübingen, 13.03.09 10 / 23 ForSyDe Crash Kurs ForSyDe’s Algebra (2) Die wichtigsten Prozessbausteine: mapSY : Bildet beliebige Haskell-Funktion auf Prozess ab mapSY :: ProcId → ProcFun (a → b) → Signal a → Signal b delaySY : Sequentielles Element; verzögert Eingabesignal delaySY :: ProcId → a → Signal a → Signal a zipSY / unzipSY : Gruppiert Signale / löst Gruppe auf. zipSY :: ProcId → Signal a → Signal b → Signal (a, b) unZipSY :: ProcId → Signal (a, b) → (Signal a, Signal b) zipWithSY : Bildet 2-stellige Haskell-Fkt auf Prozess ab. T. Häberlein, M. Brettschneider () KryptoCore-Entwurf Tübingen, 13.03.09 11 / 23 ForSyDe Crash Kurs SysDef’s newSysDef : Erzeugen einer SysDef. newSysDef :: (SysFun f ) ⇒ f → SysId → [PortId] → [PortId] → SysDef f instantiate : Erzeugen von Kopien einer SysDef. instantiate :: (SysFun f ) ⇒ ProcId → SysDef f → f T. Häberlein, M. Brettschneider () KryptoCore-Entwurf Tübingen, 13.03.09 12 / 23 ForSyDe Crash Kurs Erstes Beispiel 1 funcf beschreibt Teil des MD5 “f-Block”s: funcf :: ProcFun (Int32 → Int32 → Int32 → Int32) funcf = λ x y z → (x .&. y ) .|. ((complement x) .&. z) 2 Mit zipWith3SY wird aus funcf ein Process: funcfProc :: Signal Int32 → Signal Int32 → Signal Int32 → Signal Int32 funcfProc = zipWith3SY “funcfProc“ funcf 3 Erzeugen einer SysDef : newSysDef funcfProc “f “ [“x“, “y “, “z“] [“x“, “y “, “z“] T. Häberlein, M. Brettschneider () KryptoCore-Entwurf Tübingen, 13.03.09 13 / 23 MD5 in ForSyDe Die MD5 Hash-Funktion T. Häberlein, M. Brettschneider () KryptoCore-Entwurf Tübingen, 13.03.09 14 / 23 MD5 in ForSyDe Eine “Round” / ein “Block” f round x block ∧ x ∈ {f , g , h, i} f round = 16 sequentiell verschaltete identische f blocks. T. Häberlein, M. Brettschneider () KryptoCore-Entwurf Tübingen, 13.03.09 15 / 23 MD5 in ForSyDe Implementierung eines “Block” In ForSyDe =⇒ f block :: Int32 → Int8 → Int32 → Signal (Int32, Int32, Int32, Int32) → Signal (Int32, Int32, Int32, Int32) f block k s i abcd = abcd 0 where (a sig , b sig , c sig , d sig ) =unzip4SY “abcd“ abcd f out =funcfProc b sig c sig d sig plus out =plus4Consts k i f out a sig shift out =rotLConst s plus out cout sig =plus2Proc b sig shift out abcd 0 =zip4SY “out“ d sig cout sig b sig c sig T. Häberlein, M. Brettschneider () KryptoCore-Entwurf Tübingen, 13.03.09 16 / 23 MD5 in ForSyDe Implementierung eines x Block Besser: Eine Implementierung für alle Runden: x block :: (Signal Int32 → Signal Int32 → Signal Int32 → Signal Int32) → Int32 → Int8 → Int32 → Signal (Int32, Int32, Int32, Int32) → Signal (Int32, Int32, Int32, Int32 x block x func k s i abcd = . . . 1. Parameter: Ein Prozess (mit drei Signalen aus Eingabe und einem als Ausgabe) 2-4. Parameter: Konstanten einer x Round. Ergebnis: Prozess (mit 4er-Bündel von Signalen als Eingang und 4er-Bündel von Signalen als Ausgang). T. Häberlein, M. Brettschneider () KryptoCore-Entwurf Tübingen, 13.03.09 17 / 23 MD5 in ForSyDe Implementierung einer x Round (1) ∧ Eine “Round” = 16 sequentiell verschaltete “Blocks”. ⇒ Wir erzeugen zunächst eine Liste von 16 f Blocks: f blocks :: [ Signal (Int32, Int32, Int32, Int32) → Signal (Int32, Int32, Int32, Int32) ] f blocks = map mkInstantiation [15..0] ∧ f blocks = mkInstantiation : Bildet Zahl n auf einen f Block mit Namen f n ab. . . . und stellt die Rundenkonstanten zur Verfügung. T. Häberlein, M. Brettschneider () KryptoCore-Entwurf Tübingen, 13.03.09 18 / 23 MD5 in ForSyDe Implementierung einer x Round (2) Sequentielles Verschalten der 16 Blöcke: f round = foldl (.) id f blocks foldl (.) id kombiniert die 16 Blöcke durch Funktionskomposition: Wirkung von foldl (.) id T. Häberlein, M. Brettschneider () KryptoCore-Entwurf Tübingen, 13.03.09 19 / 23 MD6 in Haskell MD6 in Haskell 1/3 Stand der Technik parallelisierbar einfache Beschreibung mittels map/fold parallele Berechnung sequentielle Berechnung parallele Berechnung mittels map: map4 :: ((Chunk, Chunk, Chunk, Chunk) → Chunk) → [Chunk] → [Chunk] map4 f (x1 : x2 : x3 : x4 : xs) = f (x1, x2, x3, x4) : map4 f xs T. Häberlein, M. Brettschneider () KryptoCore-Entwurf Tübingen, 13.03.09 20 / 23 MD6 in Haskell MD6 in Haskell 2/3 compress ⇒ kryptografischer Kern compress : (Chunk, Chunk, Chunk, Chunk) → Chunk input der compress Funktion T. Häberlein, M. Brettschneider () KryptoCore-Entwurf Tübingen, 13.03.09 21 / 23 MD6 in Haskell MD6 in Haskell 3/3 ⇒ Haskells MD6-Version auf einem QuadCore: T. Häberlein, M. Brettschneider () KryptoCore-Entwurf Tübingen, 13.03.09 22 / 23 Literatur Literatur Jim Grundy, Tom Melham, and John OLeary. A reflective functional language for hardware design and theorem proving. Journal on Functional Programming, 16(2):157–196, 2006. Galois, Inc., Portland, Oregon. From Cryptol to FPGA, October 2008. http://www.galois.com/files/Cryptol/Cryptol Tutorial.pdf Ingo Sander and Axel Jantsch. System modeling and transformational design refinement in ForSyDe. IEEE Transactions on Computer-Aided Design of Integrated Circuits and Systems, 23(1):17–32, January 2004. Ronald L Rivest. The MD6 hash function A proposal to NIST for SHA-3. http://groups.csail.mit.edu/cis/md6/docs/ 2009-02-21-md6-report.pdf T. Häberlein, M. Brettschneider () KryptoCore-Entwurf Tübingen, 13.03.09 23 / 23