Programm (Verschlüsselung) generiert Zufallscontent



  • Hallo,
    Ich habe lange überlegt ob ich die Frage stellen soll, weil evtl. muss ich euch zumuten meinen 140+ Zeilen Code[1] zu lesen (unschön 😉 ).
    Aber nach Tagen der Fehlersuche komme ich einfach nicht mehr weiter.

    Also das Problem ist folgendes, ich hab ein Programm (besser eine Klasse) welche Text/Daten (128bit) verschlüsselt (nach dem Rabbit-Verfahren[2]).
    Nun hab ich die Klasse aus meiner Sicht fertig geschrieben und bekomme auch keine Compiler Fehler, jedoch wenn ich sie teste, dann wird nur in etwa 1 von 10 Fällen richtig codiert und decodiert.

    Das Verfahren beruht im Grunde darauf, das es S gibt (erzeugt aus interenen Variablen) welche nach jedem Codier/Decodier vorgang verändert wird.
    Und mit diesem S werden die Daten D de/codiert:

    Verschlüsselt = D XOR S
    Entschlüsselt = D XOR S

    Nun aber bekomme ich wie bereits geschrieben das nur in etwa 1/10 Fällen hin (also ich muss das Testprogramm 10 mal starten damit beim 10ten Versuch Input und Output übereinstimmen).

    Ich dachte das evtl. eine Variable mit "zufälligen"-Werten initalisiert wird aber da konnte ich nichts finden...

    Ich hoffe Ihr könnt mir helfen 😃

    PS: Ich weiß das man selbst geschriebene Verschlüsselungsimplementationen eher nicht produktiv einsetzten sollte (Sicherheitsrisiken) ist aber zum lernen ganz gut 😉

    MfG,
    Fer

    [1] Siehe hier:rabbit.cpp.zip (Klasse(cpp, hpp) und test.cpp)
    [2] www.ecrypt.eu.org


  • Mod

    Kannst du den Code anwenderfreundlicher präsentieren? Eine zip-Datei ist eine hohe Hürde, benutz lieber ein Pastebin, wenn es viel Code ist. Es wäre auch wesentlich hilfreicher, wenn du erst einmal selber versuchst, den Fehler zumindest einzukreisen. Siehe:
    http://www.c-plusplus.net/forum/304133



  • Nur mal geraten, aber folgendes gibt 0 aus:

    int main()
    {
        uint32_t i = 4294967296;
        std::cerr << i << '\n';
    }
    

    Und keine Ahnung, wie die Typen hier promoted werden:

    if(mCounter[number]+a[number]+lastCCB >= 4294967296
    


  • derFer schrieb:

    Nun aber bekomme ich wie bereits geschrieben das nur in etwa 1/10 Fällen hin (also ich muss das Testprogramm 10 mal starten damit beim 10ten Versuch Input und Output übereinstimmen).

    Ich dachte das evtl. eine Variable mit "zufälligen"-Werten initalisiert wird aber da konnte ich nichts finden...

    D.h., der Input ist immer derselbe?



  • @SeppJ: Pastbin kann ich machen aber eingrenzen ist schwer, weil ich echt nicht weiß wo der Fehler ist und wenn ich da etwas lösche ist der ganze Algorithmus kaputt.

    @knivil: Stimmt, in der Algorithmus Beschreibung steht "mod 2^32", das brauche ich hier ja aber nicht, weil das sozusagen automatisch passiert (nach 2^32 fängt die Variable ja automatisch wieder bei 0 an).

    Was das zweite an geht, da muss ich gleich mal gucken ob da der Fehler liegt, danke für den Denkanstoß.

    MfG



  • Nun, es gibt auch Sachen mit mod 2^32 in deinem Algorithmus, und wenn das nach mod 0 uebersetzt wird, dann ... keine Ahnung, was dann.

    Edit: Okay, dann kommt Integer Division Exception.



  • Hab alle Vorkommen von 2^32 (4294967296) durch ein Makro ersetzt und mal 4294967295 probiert, aber immernoch die Zufallswerte.

    @manni66: Ja der Input ist immer der selbe, hier ist mein Test:

    #include "rabbit.h"
    #include <iostream>
    
    int main(){
        uint16_t ukey[8] = {123,456,789,101,112,131,415,161};
        uint16_t utxt[8] = {  1,  2,  3,  4,  5,  6,  7,  8};
        uint16_t enc[8];
        uint16_t dec[8];
    
        rabbit Encoder(ukey);
        Encoder.encrypt(utxt,enc);
        std::cout << " codiert: ";
        for(int i = 0; i<8;i++)
            std::cout << enc[i] << " ";
        std::cout << std::endl;
    
        rabbit Decoder(ukey);
        Decoder.decrypt(enc,dec);
        std::cout << " decodiert: ";
        for(int i = 0; i<8;i++)
            std::cout << dec[i] << " ";
        std::cout << std::endl;
    }
    

    So Hier damit es nicht das Forum sprengt die Rabbit-Klasse:
    http://pastebin.com/QwFxFPQY

    Danke schon mal 🙂

    MfG



  • knivil schrieb:

    Und keine Ahnung, wie die Typen hier promoted werden:

    if(mCounter[number]+a[number]+lastCCB >= 4294967296
    

    Ja, wenn das alles uint32_t-Variablen sind, dann ist diese Abfrage völlig sinnfrei, weil der Ausdruck nie true werden kann.



  • derFer schrieb:

    So Hier damit es nicht das Forum sprengt die Rabbit-Klasse:
    http://pastebin.com/QwFxFPQY

    Dinge, die mir beim Überfliegen aufgefallen sind:

    • mach den virtuellen Destruktor da wech, das ist sinnfrei
    • Wie die Klasse zu benutzen ist, erschließt sich nicht aus ihrer Definition. Wenn encrypt/decrypt auch immer 8 16-bit werde verarbeiten, dann könntest du da ruhig int[8], out[8] statt *in und *out stehen haben, genauso wie du es beim Schlüssel gemacht hast.
    • Das mit dem IV hast du scheinbar weggelassen? Ist dir klar, wie wichtig so etwas bei Stromchriffren ist? Was ich komisch an dem von dir verlinkten Papier finde, ist dass sie es IV und nicht nonce nennen; denn wenn du verschiedene Dinge mit demselben Schlüssel verschlüsseln willst, musst du auch verschiedene IVs nehmen. Und deswegen sollte man dazu auch nonce sagen (number used once). Ein IV darf hier nämlich nicht wiederverwendet werden, ohne dass sich auch der Schlüssel ändert.
    • bwr sollte keine nicht-statische Element-Funktion sein. bwr musst du gar nicht im Header erwähnen
    • Das mit der Modulo-Arithmetik hast Du noch nicht verstanden. So kannst Du nicht auf Überläuft prüfen.


  • Danke schon mal für die Antwort 😃

    1: Der wird automatisch von Code::Blocks erzeugt, hab ich einfach so stehen lassen.
    2: Danke, hast recht. Hab ich geändert (das kommt dabei raus wenn man an zwei Tagen daran arbeitet und unterschiedliche Ideen zur Umsetzung hat 😉 ).
    3: Ja das IV hab ich weggelassen, das ist ja nicht für die Funktion von bedeutung, sondern nur für die Sicherheit, daher zum testen der Funktion erst mal eine mögliche Fehlerquelle weggelassen. Sollte alles funktionieren kommt die natürlich wieder dazu!
    4: Nicht-statische Memberfunktion?
    5: Jetzt langsam dämmert er mir, Berechnungen finden immer nur im Raum der Variablen größe statt, daher also kann ich nichts berechnen was größer als die Variable ist (Modulo zu groß).
    Aber den Modulo kann ich daher auch weglassen, da automatisch wenn es größer als 2^32 Bit ist überläuft (ist ja dann in etwa wie der Modulo 😉 ).
    Nur das mit dem Prüfen ob größer/gleich muss ich noch verbessern.

    Danke also schon mal, werde die Punkte jetzt in Angriff nehmen.

    MfG



  • So hab die Punkte mal abgearbeitet.
    Eine "Verbesserung" gibt es: es kommen keine Zufälligen Ergebnisse mehr, sondern immer das selbe falsche.

    Aber mir ist gerade folgende Idee gekommen:
    Es ist doch egal ob der Berechnungsteil innen stimmt oder nicht, er muss nur das selbe Ergebnis liefern, denn mit Welchem wert ich meine Daten XOR verknüpfe ist doch egal, solange beim zweiten mal, dem decodieren, der selbe Wert erzeugt wird zum decodieren.

    Aber scheinbar wird nicht der selbe Wert erzeugt...
    Denn jetzt erhalte ich:

    Ausgangswerte: 1 2 3 4 5 6 7 8
    codiert: 38928 30120 50620 34796 36980 63955 50589 54662
    decodiert: 33147 48141 42291 15071 15552 4838 18701 38401

    Hier so hab ich es geändert:
    http://pastebin.com/gg0UK5Xt

    MfG

    Edit:
    Immer noch nicht das gewünschte Verhalten
    Hab jetzt alle Berechnungen die überlaufen können in eine "temporäre" doppelt so große Variable verschoben.
    Aber jetzt haben sich einfach nur die Ausgaben verändert:

    codiert: 54273 4487 18024 21027 43476 22859 30737 50592
    decodiert: 40807 54071 22810 16217 8474 11500 22198 5474

    http://pastebin.com/WYCSJ8AF
    MfG



  • So Abend zusammen (interessierte Leser 😉 ),
    nach Stunden mit gdb (debugger) hab ich glaube ich die Lösung.
    Es ist nicht mehr als eine blöde Zeile Code und ich verstehe auch nicht wirklich was falsch war.

    Und zwar hab ich festgestellt das mCounterCarryBit gar nicht mit 0 initialisiert ist.
    Sondern laut Debugger einen Wert 192 hatte...
    Nach dem ich

    mCounterCarryBit = 0;
    

    aus dem Konstruktor raus in die setKey Funktion gepackt habe, klappt es (wird mit 0 initialisiert).
    Und auch der Output stimmt jetzt.

    Weitere Tests folgen.

    MfG


Log in to reply