Boring C-Compiler

rubricanis

Homo ludens
D.J. Bernstein schlägt die Entwicklung eines langweiligen C-Compilers für Kryptografie vor:

http://www.golem.de/news/daniel-j-b...compiler-fuer-bessere-crypto-1512-118149.html
https://groups.google.com/forum/m/#!msg/boring-crypto/48qa1kWignU/o8GGp2K1DAAJ

Ich stimme dem zwar zu, aber was nutzt es wenn das OS nicht sicher ist? Müsste das dann auch mit einem langweiligen C-Compiler geschrieben werden der dadurch natürlich langsameren Code generieren würde? Und hätte ein solcher Compiler nicht auch in anderen Zusammenhängen Vorzüge?

Ich frage mich ob nicht inzwischen die Frage von Laudzeiteffizenz eigentlich obsolet geworden ist, gebe aber zu dass mir das tief in der Seele eingeschrieben ist.:rolleyes:
 
Alles Mumpitz! Um 100% sicher zu sein das ein Quelltext, und damit auch jedes Programm und auch jeder Compiler, der ja auch nur ein Programm ist, genau das macht was er soll, muß man es Zeile für Zeile (und jetzt komm ich nicht auf den entsprechenden Begriff) durchgehen. So weit ich weiß, ist das nur bis auf wenige tausend Zeilen möglich da es per Hand durchgeführt werden muß.

Aber vielleicht hat sich ja inzwischen was ergeben?

PS: Diversifikation ist es nicht, aber so ähnlich.
 
Darum geht es nicht. Es geht darum dass die Sprache eindeutig definiert ist und der Compiler genau das macht was die Sprache sagt. Beide ist bei C und seinen Compilern nicht der Fall. Im übrigen gibt es m.W. heute Programme die die Richtigkeit eines Programmes beweisen können. Dazu muss man allerdings dessen Semantik genau definieren, kein unerheblicher Aufwand. Also alles kein Mumpitz!
 
Wenn der Compiler nicht macht, was die Sprache sagt, ist er kaputt und man sollte einen nehmen, der nicht kaputt ist. Und bei der Gelegenheit diese Bugs melden.
 
Da die Sprache nicht vollständig definiert ist, gibt es bei den Compilerbauern eben unterschiedliche Vorstellungen darüber wie mit undefinierten Aspekten umgegangen wird was sich zudem im Laufe der Zeit noch ändern kann. Auch das was ein Bug ist, ist u.U. relativ...:)
 
Wenn der Compiler nicht macht, was die Sprache sagt, ist er kaputt und man sollte einen nehmen, der nicht kaputt ist. Und bei der Gelegenheit diese Bugs melden.

Wenn wir das so gemacht hätten, säßen wir vermutlich Heute alle vor schwarzen Bildschirmen und es blinkt in grüner Schrift "hello world" in der ersten Zeile ...
 
C ist genau soweit spezifiziert, wie es spezifiziert sein kann. C ist eine sehr hardwarenahe Sprache, die den Anspruch hat auf jedem Computer zu laufen und nicht nur auf dem von x86 und Kollegen gebotenen Zuckerguss. Der Abgrund beginnt bei Big- und Little Endian, geht über Microcontroller mit sehr rudimentärem Speichermodell und endet bei Obskuritäten wie 36 Bit Maschinen. Dazu kommen Fragen, wie sich der jeweilige Compiler sich im Bereich der implementierungsabhgängigen Spezifikationen bewegt. Wie sich die Maschine im undefinierten Bereich verhält. Und so weiter. Das Problem liegt eher darin, dass es ohne sehr gute Kenntnis des Standards, der Implementierung und der jeweiligen Plattform schwer ist zu erkennen, was definiert ist und wo undefiniertes Verhalten beginnt. Was zwangsläufig zu Ärger führt, wenn Compilerentwickler beginnen ihre Grenzen auszuloten. Übrigens haben die meisten Compiler seit langem Optionen, um viele Fälle häufig getroffenen undefinierten Verhaltens in ein natürlich implementierungsabhängig spezifiziertes Verhalten umzuwandeln...

Statt weiter an C herumzufummeln, bin ich eher ein Freund der Idee eines C2. Lasst uns C für fertig definieren und stattdessen auf der Grundlage von C11 eine neue Sprache bauen. Sie kann zu 98% C entsprechen, darf aber inkompatibel sein. Man könnte sich auf "große" Architekturen wie x86 oder ARM konzentrieren. Man könnte grundlegende Probleme wie Felder ohne Länge oder das Fehlen eines String-Typs beheben und man könnte die inkonsistente bis gefährliche Bibliothek aufräumen. Alter Code bleibt auf C, neuer Code kann mit praktisch dem gleichen Tooling in C2 entwickelt werden. Es gab ein Paper von Poul-Henning Kamp zu der Idee, aber ich finde es leider auf die Schnelle nicht. Aber natürlich wird sich eine so radikale Idee sowieso nicht durchsetzen, dafür ist Rückkompatiblität und die Weiternutzbarkeit von uraltem Code in neuen Projekten zu wichtig.

Vor dem Hintergrund wäre schon viel gewonnen, wenn man sich gerade in der Opensource-Welt endlich einmal von der fast schon dogmatischen C-Fixierung lösen würde. Gefühlt werden - mit Ausnahme des großen Bereichs Webentwicklung - auch im Jahr 2015 ein großer Teil aller neuen Opensource-Projekte auf C begonnen. Obwohl schon ein relativ kleines Subset von C++14 (Der Kern und Klassen) die Entwicklung sicheren Codes in vielen Fällen deutlich vereinfachen könnte. Vor dem Hintergrund sind vielleicht Scott Meyers Gedanken zu inkompatiblen Änderungen an C++ interessant: http://scottmeyers.blogspot.de/2015/11/breaking-all-eggs-in-c.html
 
Oder wir hören einfach auf sicherheitskritischen Kram in C zu schreiben... Ich meine, Programmiersprachen wie ADA wurden nicht umsonst erfunden.

Ansonsten naja... würden die Compiler nicht optimieren, würden wir einen ziemlich großen Performance-Verlust erleiden. Mit O0 compilierter Code ist gerne mal nur halb so schnell wie mit O2, wenn nicht noch langsamer: http://openbenchmarking.org/result/1512150-GA-GCCOPTIMI95
 
Der Zusammenhang erschließt sich mir nicht.

@Yamagi Die Konzentration auf "große" Plattformen würde allerdings weitere Innovation verhindern und das Aufkommen neuer Plattformen noch schwerer machen als bisher. Dass SPARC und Alpha quasi tot sind, ist bedauerlich genug. Oder meinst du, es wird niemals eine neue interessante Architektur mehr geben?
 
Oder meinst du, es wird niemals eine neue interessante Architektur mehr geben?
Ich glaube, das wäre etwas gewagt. :) Aber ich denke man kann davon ausgehen, dass jede neue Architektur mit Potential x86 oder ARM anzugreifen auch ein entsprechend 'hohes' Speichermodell haben wird. Weshalb man da nicht mehr auf Microcontroller und / oder Uraltmaschinen mit z.B. klassischer Segmentuierung Rücksicht nehmen muss.
 
ARM als kleinster gemeinsamer Nenner ist vielleicht nicht immer die beste Wahl. Es gibt durchaus Gründe, Microcontroller zu verwenden, die genau das können, was man braucht. Womit soll man die dann programmieren?
 
C ist genau soweit spezifiziert, wie es spezifiziert sein kann.
Es ist nicht so spezifiziert wie es spezifiziert sein kann, sondern wie es in Hinblick auf die Zielvorstellungen, und das ist in erster Linie Laufzeiteffizens, spezifiziert ist. Natürlich wäre es ein leichtes einige Dinge strikter zu definieren, aber darunter würden eben die Optimierungsmöglichkeiten leiden. Ein Beispiel ist die Reihenfolge der Evaluierung der Funktionsargumente oder auch die offenen Arrays. Was m.E. C ausmacht ist einerseits Maschinennähe der Datentypen, andererseits ein minimales Laufzeitsystem, aber nicht die möglichen Optimierungen. Aber das sehen die Compilerbauer verständlicherweise anders.
 
Jetzt habe ich gefunden was ich suchte, es geht um Verifikation.

"Aufgabe der Verifikation eines Computerprogramms (dem Beweis der Korrektheit) ist es, zu zeigen, dass das vorliegende Programm für gewisse Eingaben terminiert. Aus der Nicht-Entscheidbarkeit des Halteproblems folgt, dass es keinen, für jedes Paar gültigen, Algorithmus gibt, der zu einem Paar (Programm, Eingabe) immer entscheiden kann, ob das Programm terminiert. Auch die Frage, ob ein Programm überall terminiert, ist unentscheidbar. Dies folgt aus einer Abwandlung des Halteproblems, dem uniformen Halteproblem."

In einer Informatikarbeitsgruppe haben wir mal als Beispiel nur ein kleines Programm durchexerziert, ca. 20 Zeilen mit einer for-Schleife. Es sollte bewiesen werden, ob das Programm terminiert; war mühselig.

https://de.wikipedia.org/wiki/Terminiertheit

https://de.wikipedia.org/wiki/Verifizierung
 
Soweit ich das verstehe sollen weitere Regeln der Auswertung von Ausdrücken hinzufügt werden damit man bereits vorher sagen kann was rauskommt unabhängig von dem was der Compiler sonst noch daraus macht. Der Beweis dass das Programm das macht was die Spezifikation definiert kommt an zweiter Stelle.
Trotzdem ist es ein Rätsel warum man unbedingt C nach Jahrzehnten aufräumen will, hat man denn nicht genug Sprachen die das besser machen?
 
In einer Informatikarbeitsgruppe haben wir mal als Beispiel nur ein kleines Programm durchexerziert, ca. 20 Zeilen mit einer for-Schleife. Es sollte bewiesen werden, ob das Programm terminiert; war mühselig.

Mein persönliches Problem mit dem akademischen Arm der Informatik und dessen Fixierung auf die mathematischen Aspekte wie Beweisbarkeit: Programme werden nicht zum Selbstzweck geschrieben. Eine Nachgewiesene Terminierbarkeit ist zwar wunderschön, aber in der Realität hängt die doch meistens von den Eingaben oder anderen Nebeneffekten ab. Das ist mathematisch natürlich sehr unschön, weswegen die funktionalen Programmiersprachen diese Nebeneffekte wegabstrahieren möchten. Leider gehen die "rein funktionalen" Programmiersprachen soweit, Nebeneffekte komplett zu leugnen, womit eine Sprache aber jeglichen Nutzen verliert, wieso möchte ich ein Programm schreiben, das nicht auf seine Umwelt reagieren kann? Wenn das EVA-Prinzip zu umständlich wird, dann sollte man sich Gedanken machen, was man überhaupt erreichen möchte. Mathematische Perfektion ist für mich ein einfach ein unerreichbares Ideal des Elfenbeinturms.

Das ist eben der krasse Gegenentwurf zur einer Minimalspezifikation wie der von C. Aber der Ansatz ist dort auch nicht Top-Down, sondern Bottom-Up: Was kann die Hardware, wie drücken wir das abseits von roher Maschinensprache aus. Aber für mich hat C noch etwas anderes, das in meinen gerade C++ fehlt, aber auch vielen anderen Sprachen: Konsistenz. Natürlich ist auch C nicht 100% konsistent, Arrays sind beispielsweise ein ziemliches Chaos. Aber gerade bei C++ habe ich viel öfter das "98%-Problem": meine Abstraktion funktioniert in 98% der Fälle super, aber in den übrigen 2 % wird das so unbequem, dass ich anfange mich zu fragen, warum ich nicht einfach von Anfang an C genommen habe (Konstruktoren, Destruktoren und Exceptions beispielsweise). Vielleicht fällt es mir auch nur deswegen so sehr auf, weil doch eigentlich ständig das Gegenteil versprochen wird.

Trotzdem ist es ein Rätsel warum man unbedingt C nach Jahrzehnten aufräumen will, hat man denn nicht genug Sprachen die das besser machen?

Weil es eine sehr einfache Sprache ist, mit schlanker Spezifikation. Außerdem, was heißt besser machen? Was willst du besser machen? Jede Sprache hat ihre eigenen Vor- und Nachteile, die perfekte Sprache gibt es nicht. Im anglikanischen Sprachraum werden Programmierer ja oft als engineers bezeichnet, damit schwingt für mich das Abwägen von Vor- und Nachteilen mit. Eine grundlegende Crypto-Bibliothek würde ich aufgrund der Performanceimplikation ungern in managed Sprachen oder sogar Python oder Ruby schreiben, dazu ist Verschlüsselung doch zu allgegenwärtig um diese Menge an Zeit und Strom zu verschwenden.
 
Zurück
Oben