Threefish selber implementieren
-
@Th69 sagte in Threefish selber implementieren:
Schon mal etwas von Debugging gehört?
Dauert zu lange da mit dem Debugger durchzugehen. Hast du auch einen konstruktiven Vorschlag?
-
@EinNutzer0 ernsthaft? Du erwartest, dass wir uns mit deinem Code beschäftigen, machst das aber selbst nicht... Ich bin gerne hilfsbereit, aber jetzt bin ich raus.
Wenn mit dem Debugger durchgehen zu lange dauert, lern ihn zu benutzen.
-
@EinNutzer0 sagte in Threefish selber implementieren:
Dauert zu lange da mit dem Debugger durchzugehen.
-
Der Code compiliert mit clang nicht einmal.
einnutzer0.cpp:95:14: error: variable-sized object may not be initialized u64 xkey[nwords] = {0}; ^~~~~~ einnutzer0.cpp:116:11: error: variable-sized object may not be initialized u64 v[nwords] = {0}; ^~~~~~ einnutzer0.cpp:149:14: error: variable-sized object may not be initialized u64 xkey[nwords] = {0}; ^~~~~~ einnutzer0.cpp:170:11: error: variable-sized object may not be initialized u64 v[nwords] = {0}; ^~~~~~ einnutzer0.cpp:206:19: error: variable-sized object may not be initialized u64 plaintext[min_array_size] = {0}; ^~~~~~~~~~~~~~ einnutzer0.cpp:214:19: error: variable-sized object may not be initialized u64 plaintext[min_array_size] = {0}; ^~~~~~~~~~~~~~ einnutzer0.cpp:223:20: error: variable-sized object may not be initialized u64 ciphertext[min_array_size] = {0}; ^~~~~~~~~~~~~~
-
Habs, wenn beide Länge 8 haben, funktioniert es schon mal...
#include <cstdint> #include <cstring> #include <iostream> #include <sstream> using namespace std; typedef uint8_t u8; typedef uint64_t u64; size_t min_len_from_string(size_t len) { while (len <= 72 * 8 || len % 8 != 0) { len++; } return len / 8; } size_t min_len_from_string_2(size_t len) { return len / 8; } void string_to_u64_array(size_t min_array_size, string s1, u64 a[]) { string s2 = ""; for (size_t i = 0; i < min_array_size * 8; i++) { s2 += s1[i % s1.length()]; } for (size_t i = 0; i < min_array_size; i++) { a[i] = 0; for (size_t j = 0; j < 8; j++) { a[i] <<= 8; a[i] |= (u8)s2[i * 8 + j]; } } } string u64_array_to_string(size_t min_array_size, u64 a[]) { string s = ""; for (size_t i = 0; i < min_array_size; i++) { u64 t = a[i]; for (size_t j = 0; j < 8; j++) { u8 c = (u8)t; s.insert(0,1,c); t >>= 8; } } return s; } u64 rl64(u64 x, u8 r) { return (x << (r & 63)) | (x >> (64 - (r & 63))); } u64 rr64(u64 x, u8 r) { return (x >> (r & 63)) | (x << (64 - (r & 63))); } void mix(u64 a, u64 b, u64 *c, u64 *d, u8 r) { u64 tmp = a + b; *d = rl64(b, r) ^ tmp; *c = tmp; } void mixinv(u64 c, u64 d, u64 *a, u64 *b, u8 r) { u64 tmp = rr64(c ^ d, r); *a = c - tmp; *b = tmp; } void threefish_round(size_t nwords, u64 v[], u8 r[], u8 p[]) { for (size_t w = 0; w < nwords; w += 2) { mix(v[p[w]], v[p[w + 1]], &v[p[w]], &v[p[w + 1]], r[w / 2]); } } void threefish_roundinv(size_t nwords, u64 v[], u8 r[], u8 p[]) { for (size_t w = 0; w < nwords; w += 2) { mixinv(v[p[w]], v[p[w + 1]], &v[p[w]], &v[p[w + 1]], r[w / 2]); } } void encrypt(size_t nwords, u64 plaintext[], u64 ciphertext[], string key) { u64 xkey[nwords] = {0}; string_to_u64_array(nwords, key, xkey); size_t nrounds = 72; u8 rot[8][2] = { {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, }; u8 perm[4][4] = { {0, 1, 2, 3}, {0, 3, 2, 1}, {0, 1, 2, 3}, {0, 3, 2, 1}, }; u64 v[nwords] = {0}; for (size_t w = 0; w < nwords; w++) { v[w] = plaintext[w]; } for (size_t n = 0; n < nrounds; n += 8) { for (size_t w = 0; w < nwords; w++) { v[w] += xkey[w]; } threefish_round(nwords, v, rot[(n + 0) % 8], perm[0]); threefish_round(nwords, v, rot[(n + 1) % 8], perm[1]); threefish_round(nwords, v, rot[(n + 2) % 8], perm[2]); threefish_round(nwords, v, rot[(n + 3) % 8], perm[3]); for (size_t w = 0; w < nwords; w++) { v[w] += xkey[w]; } threefish_round(nwords, v, rot[(n + 4) % 8], perm[0]); threefish_round(nwords, v, rot[(n + 5) % 8], perm[1]); threefish_round(nwords, v, rot[(n + 6) % 8], perm[2]); threefish_round(nwords, v, rot[(n + 7) % 8], perm[3]); } for (size_t w = 0; w < nwords; w++) { ciphertext[w] = v[w] + xkey[w]; } } void decrypt(size_t nwords, u64 plaintext[], u64 ciphertext[], string key) { u64 xkey[nwords] = {0}; string_to_u64_array(nwords, key, xkey); size_t nrounds = 72; u8 rot[8][2] = { {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, }; u8 perm[4][4] = { {0, 1, 2, 3}, {0, 3, 2, 1}, {0, 1, 2, 3}, {0, 3, 2, 1}, }; u64 v[nwords] = {0}; for (size_t w = 0; w < nwords; w++) { v[w] = ciphertext[w] - xkey[w]; } for (int n = nrounds - 8; n >= 0; n -= 8) { threefish_roundinv(nwords, v, rot[(n + 7) % 8], perm[3]); threefish_roundinv(nwords, v, rot[(n + 6) % 8], perm[2]); threefish_roundinv(nwords, v, rot[(n + 5) % 8], perm[1]); threefish_roundinv(nwords, v, rot[(n + 4) % 8], perm[0]); for (size_t w = 0; w < nwords; w++) { v[w] -= xkey[w]; } threefish_roundinv(nwords, v, rot[(n + 3) % 8], perm[3]); threefish_roundinv(nwords, v, rot[(n + 2) % 8], perm[2]); threefish_roundinv(nwords, v, rot[(n + 1) % 8], perm[1]); threefish_roundinv(nwords, v, rot[(n + 0) % 8], perm[0]); for (size_t w = 0; w < nwords; w++) { v[w] -= xkey[w]; } } for (size_t w = 0; w < nwords; w++) { plaintext[w] = v[w]; } } void encrypt_string(size_t len, size_t min_array_size, size_t min_string_size , string s, u64 ciphertext[]) { string p = "Buchstab"; u64 plaintext[min_array_size] = {0}; string_to_u64_array(len, s, plaintext); encrypt(len, plaintext, ciphertext, p); } string decrypt_string(size_t len, size_t min_array_size, size_t min_string_size , u64 ciphertext[]) { string p = "Buchstab"; u64 plaintext[min_array_size] = {0}; decrypt(len, plaintext, ciphertext, p); return u64_array_to_string(min_string_size, plaintext); } int main() { string s1 = "HhaLLoio"; size_t len = s1.length(); size_t min_array_size = min_len_from_string(len); size_t min_string_size = min_len_from_string_2(len); u64 ciphertext[min_array_size] = {0}; cout << s1 << endl; encrypt_string(len, min_array_size, min_string_size, s1, ciphertext); string s2 = decrypt_string(len, min_array_size, min_string_size, ciphertext); cout << s2 << endl; return 0; }
Das Problem war, die string Länge war zu klein, und das Ergebnis wurde umgekehrt herum zusammengesetzt...
-
@EinNutzer0 sagte in Threefish selber implementieren:
Dauert zu lange da mit dem Debugger durchzugehen. Hast du auch einen konstruktiven Vorschlag?
Dann hast du einen zentralen Punkt der Software-Entwicklung nicht verstanden.
Lern Lesen! Oder warum glaubst du dass ein Testvektor mit Nullen beginnt? Siehe auch letzten Beitrag von mir.
Fehlerreduktion erreiche ich nicht durch scharfes Ansehen des Codes (Stichwort Fehlerblindheit) sondern durch:
- Testreihen / Unittests -> Liefert der Code das richtige Ergebnis?
- Assertions -> Sind meine Annahmen korrekt?
- Debuggen -> Was geht im Code ab?
PS:
Ich koche ja auch nicht ohne abzuschmecken.
-
@EinNutzer0 sagte in Threefish selber implementieren:
@Th69 sagte in Threefish selber implementieren:
Schon mal etwas von Debugging gehört?
Dauert zu lange da mit dem Debugger durchzugehen. Hast du auch einen konstruktiven Vorschlag?
Die Anforderung an ein Minimalbeispiel hier im Forum kommt nicht von ungefähr. Auch im täglichen Business ist es sinnvoll das Problem soweit zu reduzieren, bzw. zu extrahieren, bis es überschaubar ist. Bei deinem Mini-Quellcode ist das noch recht einfach. Nutze die Zeit und lerne Debuggen. Als Entwickler sollte man seinen Debugger mindestens so gut kennen, wie den Rest der IDE.
- Abgesehen davon: "Lerne Debuggen" ist ein konstruktiver Vorschlag.
- Du bist noch lange nicht so gut, dass du es dir erlauben kannst, den alten Hasen vorzuwerfen, sie wären nicht konstruktiv.
-
Mal etwas anderes:
https://i.postimg.cc/hjdsGS38/grafik.png
Was muss ich hier umstellen, damit mich Visual Studio nicht anmeckert, dass nur Arrays mit konstanten Werten erstellt werden dürfen? Ich vermute, das ist nicht ISO-Standard...
Na ja, und zurück zum ursprünglichen Problem... Ich glaube, dass es sinnvoller ist, alles neu zu schreiben, anstatt mit dem Debugger (mehrere) Nadeln im Heuhaufen zu suchen...
... um etwas dabei zu lernen, auf jeden Fall.
-
Gar nicht, denn das gibt es in C++ schlichtweg nicht, weil wofür? Selbst in C wurden die wieder abgeschafft. Und wenn du altes C machen würdest, dann sind die auch anders gedacht als du denkst, aber das ist erst einmal egal, weil du ja kein altes C machst.
-
@EinNutzer0 sagte in Threefish selber implementieren:
Was muss ich hier umstellen, damit mich Visual Studio nicht anmeckert, dass nur Arrays mit konstanten Werten erstellt werden dürfen? Ich vermute, das ist nicht ISO-Standard...
Microsoft hatte nie einen compliant C-Compiler. Leb' Damit. Auch: Wer VLAs braucht hat die Kontrolle über sein Leben verloren.
-
Bin mit dem Debugger durch:
// ConsoleApplication1.cpp : Diese Datei enthält die Funktion "main". Hier beginnt und endet die Ausführung des Programms. // #include <cstdint> #include <cstring> #include <iostream> #include <sstream> using namespace std; typedef uint8_t u8; typedef uint64_t u64; struct sizes { const size_t len1, len2, len3; }; sizes get_sizes(const string& s) { size_t len1 = s.length(); size_t len2 = 72 * 8; if (len2 < len1) { len2 = len1; } while (len2 % 8 != 0) { len2++; } size_t len3 = len2 * 8; sizes ss{ len1, len2, len3 }; return ss; } size_t min_len_from_string(size_t len) { while (len <= 72 * 8 || len % 8 != 0) { len++; } return len / 8; } size_t min_len_from_string_2(size_t len) { return len / 8; } void string_to_u64_array(const size_t len, const string& s1, u64 a[]) { string s2 = ""; for (size_t i = 0; i < len * 8; i++) { s2 += s1[i % s1.length()]; } for (size_t i = 0; i < len; i++) { a[i] = 0; for (size_t j = 0; j < 8; j++) { a[i] <<= 8; a[i] |= (u8)s2[i * 8 + j]; } } } string u64_array_to_string(const size_t len, u64 a[]) { string s = ""; for (size_t i = 0; i < len; i++) { u64 t = a[i]; for (size_t j = 0; j < 8; j++) { u8 c = (u8)t; s.insert(0, 1, c); t >>= 8; } } return s; } u64 rl64(u64 x, u8 r) { return (x << (r & 63)) | (x >> (64 - (r & 63))); } u64 rr64(u64 x, u8 r) { return (x >> (r & 63)) | (x << (64 - (r & 63))); } void mix(u64 a, u64 b, u64* c, u64* d, u8 r) { u64 tmp = a + b; *d = rl64(b, r) ^ tmp; *c = tmp; } void mixinv(u64 c, u64 d, u64* a, u64* b, u8 r) { u64 tmp = rr64(c ^ d, r); *a = c - tmp; *b = tmp; } void threefish_round(size_t nwords, u64 v[], u8 r[], u8 p[]) { for (size_t w = 0; w < nwords; w += 2) { mix(v[p[w]], v[p[w + 1]], &v[p[w]], &v[p[w + 1]], r[w / 2]); } } void threefish_roundinv(size_t nwords, u64 v[], u8 r[], u8 p[]) { for (size_t w = 0; w < nwords; w += 2) { mixinv(v[p[w]], v[p[w + 1]], &v[p[w]], &v[p[w + 1]], r[w / 2]); } } void encrypt(size_t nwords, u64 plaintext[], u64 ciphertext[], u64 xkey[]) { size_t nrounds = 72; u8 rot[8][2] = { {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, }; u8 perm[4][4] = { {0, 1, 2, 3}, {0, 3, 2, 1}, {0, 1, 2, 3}, {0, 3, 2, 1}, }; u64* v = new u64[nwords]; for (size_t w = 0; w < nwords; w++) { v[w] = plaintext[w]; } for (size_t n = 0; n < nrounds; n += 8) { for (size_t w = 0; w < nwords; w++) { v[w] += xkey[w]; } threefish_round(nwords, v, rot[(n + 0) % 8], perm[0]); threefish_round(nwords, v, rot[(n + 1) % 8], perm[1]); threefish_round(nwords, v, rot[(n + 2) % 8], perm[2]); threefish_round(nwords, v, rot[(n + 3) % 8], perm[3]); for (size_t w = 0; w < nwords; w++) { v[w] += xkey[w]; } threefish_round(nwords, v, rot[(n + 4) % 8], perm[0]); threefish_round(nwords, v, rot[(n + 5) % 8], perm[1]); threefish_round(nwords, v, rot[(n + 6) % 8], perm[2]); threefish_round(nwords, v, rot[(n + 7) % 8], perm[3]); } for (size_t w = 0; w < nwords; w++) { ciphertext[w] = v[w] + xkey[w]; } delete[] v; } void decrypt(size_t nwords, u64 plaintext[], u64 ciphertext[], u64 xkey[]) { size_t nrounds = 72; u8 rot[8][2] = { {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, }; u8 perm[4][4] = { {0, 1, 2, 3}, {0, 3, 2, 1}, {0, 1, 2, 3}, {0, 3, 2, 1}, }; u64* v = new u64[nwords]; for (size_t w = 0; w < nwords; w++) { v[w] = ciphertext[w] - xkey[w]; } for (int n = (int)nrounds - 8; n >= 0; n -= 8) { threefish_roundinv(nwords, v, rot[(n + 7) % 8], perm[3]); threefish_roundinv(nwords, v, rot[(n + 6) % 8], perm[2]); threefish_roundinv(nwords, v, rot[(n + 5) % 8], perm[1]); threefish_roundinv(nwords, v, rot[(n + 4) % 8], perm[0]); for (size_t w = 0; w < nwords; w++) { v[w] -= xkey[w]; } threefish_roundinv(nwords, v, rot[(n + 3) % 8], perm[3]); threefish_roundinv(nwords, v, rot[(n + 2) % 8], perm[2]); threefish_roundinv(nwords, v, rot[(n + 1) % 8], perm[1]); threefish_roundinv(nwords, v, rot[(n + 0) % 8], perm[0]); for (size_t w = 0; w < nwords; w++) { v[w] -= xkey[w]; } } for (size_t w = 0; w < nwords; w++) { plaintext[w] = v[w]; } delete[] v; } string encrypt_string_with_password(const sizes ss, const string& s, const string& p) { u64* plaintext = new u64[ss.len2]; u64* ciphertext = new u64[ss.len2]; u64* xkey = new u64[ss.len2]; string_to_u64_array(ss.len2, s, plaintext); string_to_u64_array(ss.len2, p, xkey); encrypt(ss.len2, plaintext, ciphertext, xkey); string r = u64_array_to_string(ss.len2, ciphertext); delete[] plaintext, ciphertext, xkey; return r; } string decrypt_string_with_password(const sizes ss, const string& s, const string& p) { u64* plaintext = new u64[ss.len3]; u64* ciphertext = new u64[ss.len3]; u64* xkey = new u64[ss.len3]; string_to_u64_array(ss.len3, s, ciphertext); string_to_u64_array(ss.len3, p, xkey); decrypt(ss.len3, plaintext, ciphertext, xkey); string r = u64_array_to_string(ss.len1, plaintext); delete[] plaintext, ciphertext, xkey; return r; } int main() { string s = "HhaLLoio"; string p = "Buchstab"; sizes ss = get_sizes(s); string e = encrypt_string_with_password(ss, s, p); string d = decrypt_string_with_password(ss, e, p); cout << e << endl; return 0; } // Programm ausführen: STRG+F5 oder Menüeintrag "Debuggen" > "Starten ohne Debuggen starten" // Programm debuggen: F5 oder "Debuggen" > Menü "Debuggen starten" // Tipps für den Einstieg: // 1. Verwenden Sie das Projektmappen-Explorer-Fenster zum Hinzufügen/Verwalten von Dateien. // 2. Verwenden Sie das Team Explorer-Fenster zum Herstellen einer Verbindung mit der Quellcodeverwaltung. // 3. Verwenden Sie das Ausgabefenster, um die Buildausgabe und andere Nachrichten anzuzeigen. // 4. Verwenden Sie das Fenster "Fehlerliste", um Fehler anzuzeigen. // 5. Wechseln Sie zu "Projekt" > "Neues Element hinzufügen", um neue Codedateien zu erstellen, bzw. zu "Projekt" > "Vorhandenes Element hinzufügen", um dem Projekt vorhandene Codedateien hinzuzufügen. // 6. Um dieses Projekt später erneut zu öffnen, wechseln Sie zu "Datei" > "Öffnen" > "Projekt", und wählen Sie die SLN-Datei aus.
Zeile 201: C6385: Ungültige Daten werden aus "rot" gelesen.
Und genau das verstehe ich nicht, kann mir jemand helfen?
Die Speicherzugriffsverletzung erfolgt wohl in Zeile 117:
r[w / 2]);
.
-
Bin mit dem Debugger durch:
Nein bist du ganz und gar nicht. Warum weigerst du dich so vehement einen Debugger zu nutzen?
Ein kleine Internet-Recherche zu C6385 liefert: Invalid data: accessing buffer-name, the readable size is size1 bytes, but size2 bytes may be read: Lines: x, y
Du musst also einen Breakpoint in Zeile 201 legen und jeden Indize und jede Array-Größe anschauen und überprüfen. Springe unbedingt auch in die Funktion
threefish_roundinv
und überprüfe die Grenzen der Parameter.PS:
Wenn dustd::vector
oder ähnliches nutzen würdest, würdest du auch die Größen der Parameter erkennen. Denn ich frage mich in der Funktionthreefish_roundinv
wieviele Elemente der Parameterr
enthält und wie großw/2
werden kann.
-
@Quiche-Lorraine sagte in Threefish selber implementieren:
Nein bist du ganz und gar nicht. Warum weigerst du dich so vehement einen Debugger zu nutzen?
Ist das jetzt von dir eine Realitätsverweigerung oder Lügenunterstellung? (Nur als kleine Randnotiz: Ich lüge nie... das ist eine schlechte Angewohnheit. Ich würde nur in Ausnahmefällen lügen, also zum Beispiel unter Folterung usw., wenn erheblicher, unabwendbarer Schaden drohen würde. Das ist zum Teil bedingt durch meine Sozialisierung und zum anderen durch genetische Faktoren. Ich hätte doch nix davon, zu behaupten, ich hätte den Debugger verwendet, wenngleich ich ihn nicht verwendet hätte...)
Ich bin mit dem Debugger durchgegangen. Brauchst du dafür extra einen Beweis?
-
Und dann hast du dir die Variablenwerte angeschaut, wenn der Speicherzugriffsfehler erfolgt?
Das bei
threefish_round
undthreefish_roundinv
übergebene Arrayr
hat doch nur 2 Werte. Wie soll dann der Zugriff darauf mit dem Indexw / 2
in der Schleife sinnvoll sein?Soll da evtl.
w % 2
hin?
-
Ich wollte nur kurz schreiben, dass es nun geklappt hat.
// A Threefish implementation: 256bit, 4 words, 72 rounds #include <cstdint> #include <cstring> #include <iostream> #include <sstream> using namespace std; typedef uint8_t u8; typedef uint64_t u64; void string_to_u64_array(const string& s1, u64 a[4]) { const size_t len = 4; string s2 = ""; for (size_t i = 0; i < len * 8; i++) { s2.insert(0, 1, s1[i % s1.length()]); } for (size_t i = len; i > 0;) { i--; a[i] = 0; for (size_t j = 8; j > 0;) { j--; a[i] <<= 8; a[i] |= (u8)s2[i * 8 + j]; } } } string u64_array_to_string(u64 a[4]) { const size_t len = 4; string s = ""; for (size_t i = 0; i < len; i++) { u64 t = a[i]; for (size_t j = 0; j < 8; j++) { u8 c = (u8)t; s.insert(0, 1, c); t >>= 8; } } return s; } u64 rl64(u64 x, u8 r) { return (x << (r & 63)) | (x >> (64 - (r & 63))); } u64 rr64(u64 x, u8 r) { return (x >> (r & 63)) | (x << (64 - (r & 63))); } void mix(u64 a, u64 b, u64* c, u64* d, u8 r) { u64 tmp = a + b; *d = rl64(b, r) ^ tmp; *c = tmp; } void mixinv(u64 c, u64 d, u64* a, u64* b, u8 r) { u64 tmp = rr64(c ^ d, r); *a = c - tmp; *b = tmp; } void threefish_round(size_t nwords, u64 v[4], u8 r[2], u8 p[4]) { for (size_t w = 0; w < nwords; w += 2) { mix(v[p[w]], v[p[w + 1]], &v[p[w]], &v[p[w + 1]], r[w / 2]); } } void threefish_roundinv(size_t nwords, u64 v[4], u8 r[2], u8 p[4]) { for (size_t w = 0; w < nwords; w += 2) { mixinv(v[p[w]], v[p[w + 1]], &v[p[w]], &v[p[w + 1]], r[w / 2]); } } void encrypt(u64 plaintext[4], u64 ciphertext[4], u64 xkey[4]) { const size_t nwords = 4; const size_t nrounds = 72; // change it !!! u8 rot[8][2] = { {0, 0}, {5, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 6}, {0, 0}, }; u8 perm[4][4] = { {0, 1, 2, 3}, {0, 3, 2, 1}, {0, 1, 2, 3}, {0, 3, 2, 1}, }; u64* v = new u64[nwords]; for (size_t w = 0; w < nwords; w++) { v[w] = plaintext[w]; } for (size_t n = 0; n < nrounds; n += 8) { for (size_t w = 0; w < nwords; w++) { v[w] += xkey[w]; } threefish_round(nwords, v, rot[(n + 0) % 8], perm[0]); threefish_round(nwords, v, rot[(n + 1) % 8], perm[1]); threefish_round(nwords, v, rot[(n + 2) % 8], perm[2]); threefish_round(nwords, v, rot[(n + 3) % 8], perm[3]); for (size_t w = 0; w < nwords; w++) { v[w] += xkey[w]; } threefish_round(nwords, v, rot[(n + 4) % 8], perm[0]); threefish_round(nwords, v, rot[(n + 5) % 8], perm[1]); threefish_round(nwords, v, rot[(n + 6) % 8], perm[2]); threefish_round(nwords, v, rot[(n + 7) % 8], perm[3]); } for (size_t w = 0; w < nwords; w++) { ciphertext[w] = v[w] + xkey[w]; } delete[] v; } void decrypt(u64 plaintext[4], u64 ciphertext[4], u64 xkey[4]) { const size_t nwords = 4; const size_t nrounds = 72; // change it !!! u8 rot[8][2] = { {0, 0}, {5, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 6}, {0, 0}, }; u8 perm[4][4] = { {0, 1, 2, 3}, {0, 3, 2, 1}, {0, 1, 2, 3}, {0, 3, 2, 1}, }; u64* v = new u64[nwords]; for (size_t w = 0; w < nwords; w++) { v[w] = ciphertext[w] - xkey[w]; } for (size_t n = nrounds; n > 0;) { n -= 8; threefish_roundinv(nwords, v, rot[(n + 7) % 8], perm[3]); threefish_roundinv(nwords, v, rot[(n + 6) % 8], perm[2]); threefish_roundinv(nwords, v, rot[(n + 5) % 8], perm[1]); threefish_roundinv(nwords, v, rot[(n + 4) % 8], perm[0]); for (size_t w = 0; w < nwords; w++) { v[w] -= xkey[w]; } threefish_roundinv(nwords, v, rot[(n + 3) % 8], perm[3]); threefish_roundinv(nwords, v, rot[(n + 2) % 8], perm[2]); threefish_roundinv(nwords, v, rot[(n + 1) % 8], perm[1]); threefish_roundinv(nwords, v, rot[(n + 0) % 8], perm[0]); for (size_t w = 0; w < nwords; w++) { v[w] -= xkey[w]; } } for (size_t w = 0; w < nwords; w++) { plaintext[w] = v[w]; } delete[] v; } string encrypt_string_with_password(const string& s, const string& p) { u64* plaintext = new u64[4]; u64* ciphertext = new u64[4]; u64* xkey = new u64[4]; string_to_u64_array(s, plaintext); string_to_u64_array(p, xkey); encrypt(plaintext, ciphertext, xkey); string r = u64_array_to_string(ciphertext); delete[] plaintext, ciphertext, xkey; return r; } string decrypt_string_with_password(const string& s, const string& p) { u64* plaintext = new u64[4]; u64* ciphertext = new u64[4]; u64* xkey = new u64[4]; string_to_u64_array(s, ciphertext); string_to_u64_array(p, xkey); decrypt(plaintext, ciphertext, xkey); string r = u64_array_to_string(plaintext); delete[] plaintext, ciphertext, xkey; return r; } int main() { string s = "HhaLLoioBuchstab"; string p = "Buchstabbb"; string e = encrypt_string_with_password(s, p); string d = decrypt_string_with_password(e, p); cout << e << endl; cout << endl; cout << d << endl; return 0; }
Jetzt dürft ihr mich wieder bannen.
-
-
@Swordfish sagte in Threefish selber implementieren:
Es tut so weh
Beschwer dich beim Visual Studio/Microsoft, nicht bei mir.
-
@NutzerZwei Nimm an vector oder an smartpointer verdammte Axt!