[CUDA] RC6 / Serpent / Twofish / AES / MARS

AW: [CUDA] RC6 / Serpent / Twofish

Es ist wohl leider ziemlich nervig, dass deine Hardware nicht besonders viel her gibt. Kannst du nicht schon Zugriff auf das Testsystem haben oder irgendwas anderes das nicht an der untersten Grenze von den Möglichkeiten ist? Da wir kein Shared-Memory benutzen ist wohl die Anzahl der Register erschöpft. Versuch mal mit der Anzahl Threads pro Block runter zu gehen ob es dann startet.
 
AW: [CUDA] RC6 / Serpent / Twofish

Das Benchmarksystem steht in einem Rechen-Cluster auf der FH und ich hätte schon seit knapp zwei Wochen via VPN/VNC Zugriff, allerdings ist das System vor 1 Woche beim simplen Abrufen von emails (!) eingefroren und seitdem sehe ich im VNC Viewer nur noch ein schwarzes Fenster. Ich kann mich erst nach den Weihnachtsferien, wenn ich wieder auf der FH bin, darum kümmern, dass die zuständigen Leute von der Technik einen Hardreset machen. Ich selbst habe als Student auch auf der FH keinen Zutritt zu dem Raum. Und von zuhause aus kann ich schon gar nichts machen. Auf ein gesendetes Strg-Alt-Entf reagiert das System auch nicht mehr ...

Trotzdem vermute ich, dass unser aktuellstes Problem ausnahmsweise nicht an meiner 9600M GT liegt, weil man beim googeln Beiträge von Leuten mit weitaus potenterer Grafikhardware aber dem exakt selben Fehler findet. Oder läuft Twofish bei dir auf deiner GTX 560 Ti einwandfrei?

In ca. 1 h habe ich jedenfalls Zeit, am Code weiterzuarbeiten und mit der Anzahl der Threads/Blöcke herumzuprobieren. Ich melde mich dann nochmals, falls es was bewirkt. :)
 
AW: [CUDA] RC6 / Serpent / Twofish

Hab grade mal geguckt wie das ganze auf meiner GTX 560 Ti läuft und dort kriege ich nur einen "unspecified launch failure". Also Resourcen scheint die GPU genug zu haben nur mit den Pointern passt noch nicht alles. Ich habe mir auch mal ausgeben lassen wie viele Register die Funktionen brauchen und bin bei 28 Registern für die decrypt und 27 Registern für die encrypt Funktion. Bei 512 Threads pro Block macht das 14336 Register und laut der CUDA Programming Guide gibts bei Compute Capability 1.0 nur 8K Register pro Multiprocessor. Also kann auf deiner GPU der Multiprocessor keinen einzigen Block aufnehmen weil du das Limit an registern schon überschritten hast. Bei 256 Threads pro Block wärst du bei 7168 Registern pro Block was knapp unter den 8K liegt und damit laufen sollte.

Edit: Zum Vergleich haben RC6 und Serpent beide maximal 13 Register und 13*512 = 6656 und das ist auch unter 8K.
 
AW: [CUDA] RC6 / Serpent / Twofish

Habe eben mit 256 Threads / 25600 Blocks (um immer noch auf die 100 MB zu kommen) getestet und damit komme ich jetzt auf den vermutlich von dir gemeinten launch failure ...

snapshot42.png

^^ Das heißt wohl wieder, dass irgendwelche Daten, die die GPU braucht, noch nicht zuvor (korrekt) in den VRAM geschrieben werden?! Ich schau mir die ganzen mallocs nochmal an.
 
AW: [CUDA] RC6 / Serpent / Twofish / AES

AES

Ich habe gestern auch noch AES portiert, was soweit ganz gut geklappt hat, nur kriege ich da jetzt auch noch diesen blöden launch failure (und jede Menge warnings) ... :huh:
Code:
/********************************
** Advanced Encryption Standard
** Author: B-Con (b-con@b-con.us)
** Copyright/Restrictions: GNU GPL
** Disclaimer: This code is presented "as is" without any garuentees; said author holds
               liability for no problems rendered by the use of this code.
** Details: This code is the implementation of the AES algorithm, as specified by the
            NIST in in publication FIPS PUB 197, availible on the NIST website at
            http://csrc.nist.gov/publications/fips/fips197/fips-197.pdf .
******************************************/

[COLOR=royalblue][B]#include <stdio.h>[/B]
#define uchar unsigned char // 8-bit byte
#define uint unsigned long // 32-bit word

[COLOR=royalblue][B]#define HandleError(x) HandleErrorImpl(x, __FILE__, __LINE__)[/B]
// This is the specified AES SBox. To look up a substitution value, put the first
// nibble in the first index (row) and the second nibble in the second index (column).
[COLOR=royalblue][B]__device__[/B] const uchar aes_sbox[16][16] = {
   0x63,0x7C,0x77,0x7B,0xF2,0x6B,0x6F,0xC5,0x30,0x01,0x67,0x2B,0xFE,0xD7,0xAB,0x76,
   0xCA,0x82,0xC9,0x7D,0xFA,0x59,0x47,0xF0,0xAD,0xD4,0xA2,0xAF,0x9C,0xA4,0x72,0xC0,
   0xB7,0xFD,0x93,0x26,0x36,0x3F,0xF7,0xCC,0x34,0xA5,0xE5,0xF1,0x71,0xD8,0x31,0x15,
   0x04,0xC7,0x23,0xC3,0x18,0x96,0x05,0x9A,0x07,0x12,0x80,0xE2,0xEB,0x27,0xB2,0x75,
   0x09,0x83,0x2C,0x1A,0x1B,0x6E,0x5A,0xA0,0x52,0x3B,0xD6,0xB3,0x29,0xE3,0x2F,0x84,
   0x53,0xD1,0x00,0xED,0x20,0xFC,0xB1,0x5B,0x6A,0xCB,0xBE,0x39,0x4A,0x4C,0x58,0xCF,
   0xD0,0xEF,0xAA,0xFB,0x43,0x4D,0x33,0x85,0x45,0xF9,0x02,0x7F,0x50,0x3C,0x9F,0xA8,
   0x51,0xA3,0x40,0x8F,0x92,0x9D,0x38,0xF5,0xBC,0xB6,0xDA,0x21,0x10,0xFF,0xF3,0xD2,
   0xCD,0x0C,0x13,0xEC,0x5F,0x97,0x44,0x17,0xC4,0xA7,0x7E,0x3D,0x64,0x5D,0x19,0x73,
   0x60,0x81,0x4F,0xDC,0x22,0x2A,0x90,0x88,0x46,0xEE,0xB8,0x14,0xDE,0x5E,0x0B,0xDB,
   0xE0,0x32,0x3A,0x0A,0x49,0x06,0x24,0x5C,0xC2,0xD3,0xAC,0x62,0x91,0x95,0xE4,0x79,
   0xE7,0xC8,0x37,0x6D,0x8D,0xD5,0x4E,0xA9,0x6C,0x56,0xF4,0xEA,0x65,0x7A,0xAE,0x08,
   0xBA,0x78,0x25,0x2E,0x1C,0xA6,0xB4,0xC6,0xE8,0xDD,0x74,0x1F,0x4B,0xBD,0x8B,0x8A,
   0x70,0x3E,0xB5,0x66,0x48,0x03,0xF6,0x0E,0x61,0x35,0x57,0xB9,0x86,0xC1,0x1D,0x9E,
   0xE1,0xF8,0x98,0x11,0x69,0xD9,0x8E,0x94,0x9B,0x1E,0x87,0xE9,0xCE,0x55,0x28,0xDF,
   0x8C,0xA1,0x89,0x0D,0xBF,0xE6,0x42,0x68,0x41,0x99,0x2D,0x0F,0xB0,0x54,0xBB,0x16
};

[COLOR=royalblue][B]__device__[/B] const uchar aes_invsbox[16][16] = {
   0x52,0x09,0x6A,0xD5,0x30,0x36,0xA5,0x38,0xBF,0x40,0xA3,0x9E,0x81,0xF3,0xD7,0xFB,
   0x7C,0xE3,0x39,0x82,0x9B,0x2F,0xFF,0x87,0x34,0x8E,0x43,0x44,0xC4,0xDE,0xE9,0xCB,
   0x54,0x7B,0x94,0x32,0xA6,0xC2,0x23,0x3D,0xEE,0x4C,0x95,0x0B,0x42,0xFA,0xC3,0x4E,
   0x08,0x2E,0xA1,0x66,0x28,0xD9,0x24,0xB2,0x76,0x5B,0xA2,0x49,0x6D,0x8B,0xD1,0x25,
   0x72,0xF8,0xF6,0x64,0x86,0x68,0x98,0x16,0xD4,0xA4,0x5C,0xCC,0x5D,0x65,0xB6,0x92,
   0x6C,0x70,0x48,0x50,0xFD,0xED,0xB9,0xDA,0x5E,0x15,0x46,0x57,0xA7,0x8D,0x9D,0x84,
   0x90,0xD8,0xAB,0x00,0x8C,0xBC,0xD3,0x0A,0xF7,0xE4,0x58,0x05,0xB8,0xB3,0x45,0x06,
   0xD0,0x2C,0x1E,0x8F,0xCA,0x3F,0x0F,0x02,0xC1,0xAF,0xBD,0x03,0x01,0x13,0x8A,0x6B,
   0x3A,0x91,0x11,0x41,0x4F,0x67,0xDC,0xEA,0x97,0xF2,0xCF,0xCE,0xF0,0xB4,0xE6,0x73,
   0x96,0xAC,0x74,0x22,0xE7,0xAD,0x35,0x85,0xE2,0xF9,0x37,0xE8,0x1C,0x75,0xDF,0x6E,
   0x47,0xF1,0x1A,0x71,0x1D,0x29,0xC5,0x89,0x6F,0xB7,0x62,0x0E,0xAA,0x18,0xBE,0x1B,
   0xFC,0x56,0x3E,0x4B,0xC6,0xD2,0x79,0x20,0x9A,0xDB,0xC0,0xFE,0x78,0xCD,0x5A,0xF4,
   0x1F,0xDD,0xA8,0x33,0x88,0x07,0xC7,0x31,0xB1,0x12,0x10,0x59,0x27,0x80,0xEC,0x5F,
   0x60,0x51,0x7F,0xA9,0x19,0xB5,0x4A,0x0D,0x2D,0xE5,0x7A,0x9F,0x93,0xC9,0x9C,0xEF,
   0xA0,0xE0,0x3B,0x4D,0xAE,0x2A,0xF5,0xB0,0xC8,0xEB,0xBB,0x3C,0x83,0x53,0x99,0x61,
   0x17,0x2B,0x04,0x7E,0xBA,0x77,0xD6,0x26,0xE1,0x69,0x14,0x63,0x55,0x21,0x0C,0x7D
};

// - This table stores pre-calculated values for all possible GF(2^8) calculations.This
// table is only used by the (Inv)MixColumns steps.
// USAGE: The second index (column) is the coefficient of multiplication. Only 7 different
// coefficients are used: 0x01, 0x02, 0x03, 0x09, 0x0b, 0x0d, 0x0e, but multiplication by
// 1 is negligible leaving only 6 coefficients. Each column of the table is devoted to one
// of these coefficients, in the ascending order of value, from values 0x00 to 0xFF.
// (Columns are listed double-wide to conserve vertical space.)
[COLOR=royalblue][B]__device__[/B] uchar gf_mul[256][6] = {
   {0x00,0x00,0x00,0x00,0x00,0x00},{0x02,0x03,0x09,0x0b,0x0d,0x0e},
   {0x04,0x06,0x12,0x16,0x1a,0x1c},{0x06,0x05,0x1b,0x1d,0x17,0x12},
   {0x08,0x0c,0x24,0x2c,0x34,0x38},{0x0a,0x0f,0x2d,0x27,0x39,0x36},
   {0x0c,0x0a,0x36,0x3a,0x2e,0x24},{0x0e,0x09,0x3f,0x31,0x23,0x2a},
   {0x10,0x18,0x48,0x58,0x68,0x70},{0x12,0x1b,0x41,0x53,0x65,0x7e},
   {0x14,0x1e,0x5a,0x4e,0x72,0x6c},{0x16,0x1d,0x53,0x45,0x7f,0x62},
   {0x18,0x14,0x6c,0x74,0x5c,0x48},{0x1a,0x17,0x65,0x7f,0x51,0x46},
   {0x1c,0x12,0x7e,0x62,0x46,0x54},{0x1e,0x11,0x77,0x69,0x4b,0x5a},
   {0x20,0x30,0x90,0xb0,0xd0,0xe0},{0x22,0x33,0x99,0xbb,0xdd,0xee},
   {0x24,0x36,0x82,0xa6,0xca,0xfc},{0x26,0x35,0x8b,0xad,0xc7,0xf2},
   {0x28,0x3c,0xb4,0x9c,0xe4,0xd8},{0x2a,0x3f,0xbd,0x97,0xe9,0xd6},
   {0x2c,0x3a,0xa6,0x8a,0xfe,0xc4},{0x2e,0x39,0xaf,0x81,0xf3,0xca},
   {0x30,0x28,0xd8,0xe8,0xb8,0x90},{0x32,0x2b,0xd1,0xe3,0xb5,0x9e},
   {0x34,0x2e,0xca,0xfe,0xa2,0x8c},{0x36,0x2d,0xc3,0xf5,0xaf,0x82},
   {0x38,0x24,0xfc,0xc4,0x8c,0xa8},{0x3a,0x27,0xf5,0xcf,0x81,0xa6},
   {0x3c,0x22,0xee,0xd2,0x96,0xb4},{0x3e,0x21,0xe7,0xd9,0x9b,0xba},
   {0x40,0x60,0x3b,0x7b,0xbb,0xdb},{0x42,0x63,0x32,0x70,0xb6,0xd5},
   {0x44,0x66,0x29,0x6d,0xa1,0xc7},{0x46,0x65,0x20,0x66,0xac,0xc9},
   {0x48,0x6c,0x1f,0x57,0x8f,0xe3},{0x4a,0x6f,0x16,0x5c,0x82,0xed},
   {0x4c,0x6a,0x0d,0x41,0x95,0xff},{0x4e,0x69,0x04,0x4a,0x98,0xf1},
   {0x50,0x78,0x73,0x23,0xd3,0xab},{0x52,0x7b,0x7a,0x28,0xde,0xa5},
   {0x54,0x7e,0x61,0x35,0xc9,0xb7},{0x56,0x7d,0x68,0x3e,0xc4,0xb9},
   {0x58,0x74,0x57,0x0f,0xe7,0x93},{0x5a,0x77,0x5e,0x04,0xea,0x9d},
   {0x5c,0x72,0x45,0x19,0xfd,0x8f},{0x5e,0x71,0x4c,0x12,0xf0,0x81},
   {0x60,0x50,0xab,0xcb,0x6b,0x3b},{0x62,0x53,0xa2,0xc0,0x66,0x35},
   {0x64,0x56,0xb9,0xdd,0x71,0x27},{0x66,0x55,0xb0,0xd6,0x7c,0x29},
   {0x68,0x5c,0x8f,0xe7,0x5f,0x03},{0x6a,0x5f,0x86,0xec,0x52,0x0d},
   {0x6c,0x5a,0x9d,0xf1,0x45,0x1f},{0x6e,0x59,0x94,0xfa,0x48,0x11},
   {0x70,0x48,0xe3,0x93,0x03,0x4b},{0x72,0x4b,0xea,0x98,0x0e,0x45},
   {0x74,0x4e,0xf1,0x85,0x19,0x57},{0x76,0x4d,0xf8,0x8e,0x14,0x59},
   {0x78,0x44,0xc7,0xbf,0x37,0x73},{0x7a,0x47,0xce,0xb4,0x3a,0x7d},
   {0x7c,0x42,0xd5,0xa9,0x2d,0x6f},{0x7e,0x41,0xdc,0xa2,0x20,0x61},
   {0x80,0xc0,0x76,0xf6,0x6d,0xad},{0x82,0xc3,0x7f,0xfd,0x60,0xa3},
   {0x84,0xc6,0x64,0xe0,0x77,0xb1},{0x86,0xc5,0x6d,0xeb,0x7a,0xbf},
   {0x88,0xcc,0x52,0xda,0x59,0x95},{0x8a,0xcf,0x5b,0xd1,0x54,0x9b},
   {0x8c,0xca,0x40,0xcc,0x43,0x89},{0x8e,0xc9,0x49,0xc7,0x4e,0x87},
   {0x90,0xd8,0x3e,0xae,0x05,0xdd},{0x92,0xdb,0x37,0xa5,0x08,0xd3},
   {0x94,0xde,0x2c,0xb8,0x1f,0xc1},{0x96,0xdd,0x25,0xb3,0x12,0xcf},
   {0x98,0xd4,0x1a,0x82,0x31,0xe5},{0x9a,0xd7,0x13,0x89,0x3c,0xeb},
   {0x9c,0xd2,0x08,0x94,0x2b,0xf9},{0x9e,0xd1,0x01,0x9f,0x26,0xf7},
   {0xa0,0xf0,0xe6,0x46,0xbd,0x4d},{0xa2,0xf3,0xef,0x4d,0xb0,0x43},
   {0xa4,0xf6,0xf4,0x50,0xa7,0x51},{0xa6,0xf5,0xfd,0x5b,0xaa,0x5f},
   {0xa8,0xfc,0xc2,0x6a,0x89,0x75},{0xaa,0xff,0xcb,0x61,0x84,0x7b},
   {0xac,0xfa,0xd0,0x7c,0x93,0x69},{0xae,0xf9,0xd9,0x77,0x9e,0x67},
   {0xb0,0xe8,0xae,0x1e,0xd5,0x3d},{0xb2,0xeb,0xa7,0x15,0xd8,0x33},
   {0xb4,0xee,0xbc,0x08,0xcf,0x21},{0xb6,0xed,0xb5,0x03,0xc2,0x2f},
   {0xb8,0xe4,0x8a,0x32,0xe1,0x05},{0xba,0xe7,0x83,0x39,0xec,0x0b},
   {0xbc,0xe2,0x98,0x24,0xfb,0x19},{0xbe,0xe1,0x91,0x2f,0xf6,0x17},
   {0xc0,0xa0,0x4d,0x8d,0xd6,0x76},{0xc2,0xa3,0x44,0x86,0xdb,0x78},
   {0xc4,0xa6,0x5f,0x9b,0xcc,0x6a},{0xc6,0xa5,0x56,0x90,0xc1,0x64},
   {0xc8,0xac,0x69,0xa1,0xe2,0x4e},{0xca,0xaf,0x60,0xaa,0xef,0x40},
   {0xcc,0xaa,0x7b,0xb7,0xf8,0x52},{0xce,0xa9,0x72,0xbc,0xf5,0x5c},
   {0xd0,0xb8,0x05,0xd5,0xbe,0x06},{0xd2,0xbb,0x0c,0xde,0xb3,0x08},
   {0xd4,0xbe,0x17,0xc3,0xa4,0x1a},{0xd6,0xbd,0x1e,0xc8,0xa9,0x14},
   {0xd8,0xb4,0x21,0xf9,0x8a,0x3e},{0xda,0xb7,0x28,0xf2,0x87,0x30},
   {0xdc,0xb2,0x33,0xef,0x90,0x22},{0xde,0xb1,0x3a,0xe4,0x9d,0x2c},
   {0xe0,0x90,0xdd,0x3d,0x06,0x96},{0xe2,0x93,0xd4,0x36,0x0b,0x98},
   {0xe4,0x96,0xcf,0x2b,0x1c,0x8a},{0xe6,0x95,0xc6,0x20,0x11,0x84},
   {0xe8,0x9c,0xf9,0x11,0x32,0xae},{0xea,0x9f,0xf0,0x1a,0x3f,0xa0},
   {0xec,0x9a,0xeb,0x07,0x28,0xb2},{0xee,0x99,0xe2,0x0c,0x25,0xbc},
   {0xf0,0x88,0x95,0x65,0x6e,0xe6},{0xf2,0x8b,0x9c,0x6e,0x63,0xe8},
   {0xf4,0x8e,0x87,0x73,0x74,0xfa},{0xf6,0x8d,0x8e,0x78,0x79,0xf4},
   {0xf8,0x84,0xb1,0x49,0x5a,0xde},{0xfa,0x87,0xb8,0x42,0x57,0xd0},
   {0xfc,0x82,0xa3,0x5f,0x40,0xc2},{0xfe,0x81,0xaa,0x54,0x4d,0xcc},
   {0x1b,0x9b,0xec,0xf7,0xda,0x41},{0x19,0x98,0xe5,0xfc,0xd7,0x4f},
   {0x1f,0x9d,0xfe,0xe1,0xc0,0x5d},{0x1d,0x9e,0xf7,0xea,0xcd,0x53},
   {0x13,0x97,0xc8,0xdb,0xee,0x79},{0x11,0x94,0xc1,0xd0,0xe3,0x77},
   {0x17,0x91,0xda,0xcd,0xf4,0x65},{0x15,0x92,0xd3,0xc6,0xf9,0x6b},
   {0x0b,0x83,0xa4,0xaf,0xb2,0x31},{0x09,0x80,0xad,0xa4,0xbf,0x3f},
   {0x0f,0x85,0xb6,0xb9,0xa8,0x2d},{0x0d,0x86,0xbf,0xb2,0xa5,0x23},
   {0x03,0x8f,0x80,0x83,0x86,0x09},{0x01,0x8c,0x89,0x88,0x8b,0x07},
   {0x07,0x89,0x92,0x95,0x9c,0x15},{0x05,0x8a,0x9b,0x9e,0x91,0x1b},
   {0x3b,0xab,0x7c,0x47,0x0a,0xa1},{0x39,0xa8,0x75,0x4c,0x07,0xaf},
   {0x3f,0xad,0x6e,0x51,0x10,0xbd},{0x3d,0xae,0x67,0x5a,0x1d,0xb3},
   {0x33,0xa7,0x58,0x6b,0x3e,0x99},{0x31,0xa4,0x51,0x60,0x33,0x97},
   {0x37,0xa1,0x4a,0x7d,0x24,0x85},{0x35,0xa2,0x43,0x76,0x29,0x8b},
   {0x2b,0xb3,0x34,0x1f,0x62,0xd1},{0x29,0xb0,0x3d,0x14,0x6f,0xdf},
   {0x2f,0xb5,0x26,0x09,0x78,0xcd},{0x2d,0xb6,0x2f,0x02,0x75,0xc3},
   {0x23,0xbf,0x10,0x33,0x56,0xe9},{0x21,0xbc,0x19,0x38,0x5b,0xe7},
   {0x27,0xb9,0x02,0x25,0x4c,0xf5},{0x25,0xba,0x0b,0x2e,0x41,0xfb},
   {0x5b,0xfb,0xd7,0x8c,0x61,0x9a},{0x59,0xf8,0xde,0x87,0x6c,0x94},
   {0x5f,0xfd,0xc5,0x9a,0x7b,0x86},{0x5d,0xfe,0xcc,0x91,0x76,0x88},
   {0x53,0xf7,0xf3,0xa0,0x55,0xa2},{0x51,0xf4,0xfa,0xab,0x58,0xac},
   {0x57,0xf1,0xe1,0xb6,0x4f,0xbe},{0x55,0xf2,0xe8,0xbd,0x42,0xb0},
   {0x4b,0xe3,0x9f,0xd4,0x09,0xea},{0x49,0xe0,0x96,0xdf,0x04,0xe4},
   {0x4f,0xe5,0x8d,0xc2,0x13,0xf6},{0x4d,0xe6,0x84,0xc9,0x1e,0xf8},
   {0x43,0xef,0xbb,0xf8,0x3d,0xd2},{0x41,0xec,0xb2,0xf3,0x30,0xdc},
   {0x47,0xe9,0xa9,0xee,0x27,0xce},{0x45,0xea,0xa0,0xe5,0x2a,0xc0},
   {0x7b,0xcb,0x47,0x3c,0xb1,0x7a},{0x79,0xc8,0x4e,0x37,0xbc,0x74},
   {0x7f,0xcd,0x55,0x2a,0xab,0x66},{0x7d,0xce,0x5c,0x21,0xa6,0x68},
   {0x73,0xc7,0x63,0x10,0x85,0x42},{0x71,0xc4,0x6a,0x1b,0x88,0x4c},
   {0x77,0xc1,0x71,0x06,0x9f,0x5e},{0x75,0xc2,0x78,0x0d,0x92,0x50},
   {0x6b,0xd3,0x0f,0x64,0xd9,0x0a},{0x69,0xd0,0x06,0x6f,0xd4,0x04},
   {0x6f,0xd5,0x1d,0x72,0xc3,0x16},{0x6d,0xd6,0x14,0x79,0xce,0x18},
   {0x63,0xdf,0x2b,0x48,0xed,0x32},{0x61,0xdc,0x22,0x43,0xe0,0x3c},
   {0x67,0xd9,0x39,0x5e,0xf7,0x2e},{0x65,0xda,0x30,0x55,0xfa,0x20},
   {0x9b,0x5b,0x9a,0x01,0xb7,0xec},{0x99,0x58,0x93,0x0a,0xba,0xe2},
   {0x9f,0x5d,0x88,0x17,0xad,0xf0},{0x9d,0x5e,0x81,0x1c,0xa0,0xfe},
   {0x93,0x57,0xbe,0x2d,0x83,0xd4},{0x91,0x54,0xb7,0x26,0x8e,0xda},
   {0x97,0x51,0xac,0x3b,0x99,0xc8},{0x95,0x52,0xa5,0x30,0x94,0xc6},
   {0x8b,0x43,0xd2,0x59,0xdf,0x9c},{0x89,0x40,0xdb,0x52,0xd2,0x92},
   {0x8f,0x45,0xc0,0x4f,0xc5,0x80},{0x8d,0x46,0xc9,0x44,0xc8,0x8e},
   {0x83,0x4f,0xf6,0x75,0xeb,0xa4},{0x81,0x4c,0xff,0x7e,0xe6,0xaa},
   {0x87,0x49,0xe4,0x63,0xf1,0xb8},{0x85,0x4a,0xed,0x68,0xfc,0xb6},
   {0xbb,0x6b,0x0a,0xb1,0x67,0x0c},{0xb9,0x68,0x03,0xba,0x6a,0x02},
   {0xbf,0x6d,0x18,0xa7,0x7d,0x10},{0xbd,0x6e,0x11,0xac,0x70,0x1e},
   {0xb3,0x67,0x2e,0x9d,0x53,0x34},{0xb1,0x64,0x27,0x96,0x5e,0x3a},
   {0xb7,0x61,0x3c,0x8b,0x49,0x28},{0xb5,0x62,0x35,0x80,0x44,0x26},
   {0xab,0x73,0x42,0xe9,0x0f,0x7c},{0xa9,0x70,0x4b,0xe2,0x02,0x72},
   {0xaf,0x75,0x50,0xff,0x15,0x60},{0xad,0x76,0x59,0xf4,0x18,0x6e},
   {0xa3,0x7f,0x66,0xc5,0x3b,0x44},{0xa1,0x7c,0x6f,0xce,0x36,0x4a},
   {0xa7,0x79,0x74,0xd3,0x21,0x58},{0xa5,0x7a,0x7d,0xd8,0x2c,0x56},
   {0xdb,0x3b,0xa1,0x7a,0x0c,0x37},{0xd9,0x38,0xa8,0x71,0x01,0x39},
   {0xdf,0x3d,0xb3,0x6c,0x16,0x2b},{0xdd,0x3e,0xba,0x67,0x1b,0x25},
   {0xd3,0x37,0x85,0x56,0x38,0x0f},{0xd1,0x34,0x8c,0x5d,0x35,0x01},
   {0xd7,0x31,0x97,0x40,0x22,0x13},{0xd5,0x32,0x9e,0x4b,0x2f,0x1d},
   {0xcb,0x23,0xe9,0x22,0x64,0x47},{0xc9,0x20,0xe0,0x29,0x69,0x49},
   {0xcf,0x25,0xfb,0x34,0x7e,0x5b},{0xcd,0x26,0xf2,0x3f,0x73,0x55},
   {0xc3,0x2f,0xcd,0x0e,0x50,0x7f},{0xc1,0x2c,0xc4,0x05,0x5d,0x71},
   {0xc7,0x29,0xdf,0x18,0x4a,0x63},{0xc5,0x2a,0xd6,0x13,0x47,0x6d},
   {0xfb,0x0b,0x31,0xca,0xdc,0xd7},{0xf9,0x08,0x38,0xc1,0xd1,0xd9},
   {0xff,0x0d,0x23,0xdc,0xc6,0xcb},{0xfd,0x0e,0x2a,0xd7,0xcb,0xc5},
   {0xf3,0x07,0x15,0xe6,0xe8,0xef},{0xf1,0x04,0x1c,0xed,0xe5,0xe1},
   {0xf7,0x01,0x07,0xf0,0xf2,0xf3},{0xf5,0x02,0x0e,0xfb,0xff,0xfd},
   {0xeb,0x13,0x79,0x92,0xb4,0xa7},{0xe9,0x10,0x70,0x99,0xb9,0xa9},
   {0xef,0x15,0x6b,0x84,0xae,0xbb},{0xed,0x16,0x62,0x8f,0xa3,0xb5},
   {0xe3,0x1f,0x5d,0xbe,0x80,0x9f},{0xe1,0x1c,0x54,0xb5,0x8d,0x91},
   {0xe7,0x19,0x4f,0xa8,0x9a,0x83},{0xe5,0x1a,0x46,0xa3,0x97,0x8d}
};

/********************
** ADD ROUND KEY
********************/

// Performs the AddRoundKey step. Each round has its own pre-generated 16-byte key in the
// form of 4 integers (the "w" array). Each integer is XOR'd by one column of the state.
// Also performs the job of InvAddRoundKey(); since the function is a simple XOR process,
// it is its own inverse.
[COLOR=royalblue][B]__host__ __device__[/B] void AddRoundKey(uchar state[][4], uint w[])
{
   uchar subkey[4];
   // memcpy(subkey,&w[idx],4); // Not accurate for big endian machines
   // Subkey 1
   subkey[0] = w[0] >> 24;
   subkey[1] = w[0] >> 16;
   subkey[2] = w[0] >> 8;
   subkey[3] = w[0];
   state[0][0] ^= subkey[0];
   state[1][0] ^= subkey[1];
   state[2][0] ^= subkey[2];
   state[3][0] ^= subkey[3];
   // Subkey 2
   subkey[0] = w[1] >> 24;
   subkey[1] = w[1] >> 16;
   subkey[2] = w[1] >> 8;
   subkey[3] = w[1];
   state[0][1] ^= subkey[0];
   state[1][1] ^= subkey[1];
   state[2][1] ^= subkey[2];
   state[3][1] ^= subkey[3];
   // Subkey 3
   subkey[0] = w[2] >> 24;
   subkey[1] = w[2] >> 16;
   subkey[2] = w[2] >> 8;
   subkey[3] = w[2];
   state[0][2] ^= subkey[0];
   state[1][2] ^= subkey[1];
   state[2][2] ^= subkey[2];
   state[3][2] ^= subkey[3];
   // Subkey 4
   subkey[0] = w[3] >> 24;
   subkey[1] = w[3] >> 16;
   subkey[2] = w[3] >> 8;
   subkey[3] = w[3];
   state[0][3] ^= subkey[0];
   state[1][3] ^= subkey[1];
   state[2][3] ^= subkey[2];
   state[3][3] ^= subkey[3];
}

/********************
** (Inv)SubBytes
********************/

// Performs the SubBytes step. All bytes in the state are substituted with a
// pre-calculated value from a lookup table.
[COLOR=royalblue][B]__host__ __device__[/B] void SubBytes(uchar state[][4])
{
   state[0][0] = aes_sbox[state[0][0] >> 4][state[0][0] & 0x0F];
   state[0][1] = aes_sbox[state[0][1] >> 4][state[0][1] & 0x0F];
   state[0][2] = aes_sbox[state[0][2] >> 4][state[0][2] & 0x0F];
   state[0][3] = aes_sbox[state[0][3] >> 4][state[0][3] & 0x0F];
   state[1][0] = aes_sbox[state[1][0] >> 4][state[1][0] & 0x0F];
   state[1][1] = aes_sbox[state[1][1] >> 4][state[1][1] & 0x0F];
   state[1][2] = aes_sbox[state[1][2] >> 4][state[1][2] & 0x0F];
   state[1][3] = aes_sbox[state[1][3] >> 4][state[1][3] & 0x0F];
   state[2][0] = aes_sbox[state[2][0] >> 4][state[2][0] & 0x0F];
   state[2][1] = aes_sbox[state[2][1] >> 4][state[2][1] & 0x0F];
   state[2][2] = aes_sbox[state[2][2] >> 4][state[2][2] & 0x0F];
   state[2][3] = aes_sbox[state[2][3] >> 4][state[2][3] & 0x0F];
   state[3][0] = aes_sbox[state[3][0] >> 4][state[3][0] & 0x0F];
   state[3][1] = aes_sbox[state[3][1] >> 4][state[3][1] & 0x0F];
   state[3][2] = aes_sbox[state[3][2] >> 4][state[3][2] & 0x0F];
   state[3][3] = aes_sbox[state[3][3] >> 4][state[3][3] & 0x0F];
}

[COLOR=royalblue][B]__host__ __device__[/B] void InvSubBytes(uchar state[][4])
{
   state[0][0] = aes_invsbox[state[0][0] >> 4][state[0][0] & 0x0F];
   state[0][1] = aes_invsbox[state[0][1] >> 4][state[0][1] & 0x0F];
   state[0][2] = aes_invsbox[state[0][2] >> 4][state[0][2] & 0x0F];
   state[0][3] = aes_invsbox[state[0][3] >> 4][state[0][3] & 0x0F];
   state[1][0] = aes_invsbox[state[1][0] >> 4][state[1][0] & 0x0F];
   state[1][1] = aes_invsbox[state[1][1] >> 4][state[1][1] & 0x0F];
   state[1][2] = aes_invsbox[state[1][2] >> 4][state[1][2] & 0x0F];
   state[1][3] = aes_invsbox[state[1][3] >> 4][state[1][3] & 0x0F];
   state[2][0] = aes_invsbox[state[2][0] >> 4][state[2][0] & 0x0F];
   state[2][1] = aes_invsbox[state[2][1] >> 4][state[2][1] & 0x0F];
   state[2][2] = aes_invsbox[state[2][2] >> 4][state[2][2] & 0x0F];
   state[2][3] = aes_invsbox[state[2][3] >> 4][state[2][3] & 0x0F];
   state[3][0] = aes_invsbox[state[3][0] >> 4][state[3][0] & 0x0F];
   state[3][1] = aes_invsbox[state[3][1] >> 4][state[3][1] & 0x0F];
   state[3][2] = aes_invsbox[state[3][2] >> 4][state[3][2] & 0x0F];
   state[3][3] = aes_invsbox[state[3][3] >> 4][state[3][3] & 0x0F];
}

/********************
** (Inv)ShiftRows
********************/

// Performs the ShiftRows step. All rows are shifted cylindrically to the left.
[COLOR=royalblue][B]__host__ __device__[/B] void ShiftRows(uchar state[][4])
{
   int t;
   // Shift left by 1
   t = state[1][0];
   state[1][0] = state[1][1];
   state[1][1] = state[1][2];
   state[1][2] = state[1][3];
   state[1][3] = t;
   // Shift left by 2
   t = state[2][0];
   state[2][0] = state[2][2];
   state[2][2] = t;
   t = state[2][1];
   state[2][1] = state[2][3];
   state[2][3] = t;
   // Shift left by 3
   t = state[3][0];
   state[3][0] = state[3][3];
   state[3][3] = state[3][2];
   state[3][2] = state[3][1];
   state[3][1] = t;
}

// All rows are shifted cylindrically to the right.
[COLOR=royalblue][B]__host__ __device__[/B] void InvShiftRows(uchar state[][4])
{
   int t;
   // Shift right by 1
   t = state[1][3];
   state[1][3] = state[1][2];
   state[1][2] = state[1][1];
   state[1][1] = state[1][0];
   state[1][0] = t;
   // Shift right by 2
   t = state[2][3];
   state[2][3] = state[2][1];
   state[2][1] = t;
   t = state[2][2];
   state[2][2] = state[2][0];
   state[2][0] = t;
   // Shift right by 3
   t = state[3][3];
   state[3][3] = state[3][0];
   state[3][0] = state[3][1];
   state[3][1] = state[3][2];
   state[3][2] = t;
}

/********************
** (Inv)MixColumns
********************/

// Performs the MixColums step. The state is multiplied by itself using matrix
// multiplication in a Galios Field 2^8. All multiplication is pre-computed in a table.
// Addition is equivilent to XOR. (Must always make a copy of the column as the original
// values will be destoyed.)
[COLOR=royalblue][B]__host__ __device__[/B] void MixColumns(uchar state[][4])
{
   uchar col[4];
   // Column 1
   col[0] = state[0][0];
   col[1] = state[1][0];
   col[2] = state[2][0];
   col[3] = state[3][0];
   state[0][0] = gf_mul[col[0]][0];
   state[0][0] ^= gf_mul[col[1]][1];
   state[0][0] ^= col[2];
   state[0][0] ^= col[3];
   state[1][0] = col[0];
   state[1][0] ^= gf_mul[col[1]][0];
   state[1][0] ^= gf_mul[col[2]][1];
   state[1][0] ^= col[3];
   state[2][0] = col[0];
   state[2][0] ^= col[1];
   state[2][0] ^= gf_mul[col[2]][0];
   state[2][0] ^= gf_mul[col[3]][1];
   state[3][0] = gf_mul[col[0]][1];
   state[3][0] ^= col[1];
   state[3][0] ^= col[2];
   state[3][0] ^= gf_mul[col[3]][0];
   // Column 2
   col[0] = state[0][1];
   col[1] = state[1][1];
   col[2] = state[2][1];
   col[3] = state[3][1];
   state[0][1] = gf_mul[col[0]][0];
   state[0][1] ^= gf_mul[col[1]][1];
   state[0][1] ^= col[2];
   state[0][1] ^= col[3];
   state[1][1] = col[0];
   state[1][1] ^= gf_mul[col[1]][0];
   state[1][1] ^= gf_mul[col[2]][1];
   state[1][1] ^= col[3];
   state[2][1] = col[0];
   state[2][1] ^= col[1];
   state[2][1] ^= gf_mul[col[2]][0];
   state[2][1] ^= gf_mul[col[3]][1];
   state[3][1] = gf_mul[col[0]][1];
   state[3][1] ^= col[1];
   state[3][1] ^= col[2];
   state[3][1] ^= gf_mul[col[3]][0];
   // Column 3
   col[0] = state[0][2];
   col[1] = state[1][2];
   col[2] = state[2][2];
   col[3] = state[3][2];
   state[0][2] = gf_mul[col[0]][0];
   state[0][2] ^= gf_mul[col[1]][1];
   state[0][2] ^= col[2];
   state[0][2] ^= col[3];
   state[1][2] = col[0];
   state[1][2] ^= gf_mul[col[1]][0];
   state[1][2] ^= gf_mul[col[2]][1];
   state[1][2] ^= col[3];
   state[2][2] = col[0];
   state[2][2] ^= col[1];
   state[2][2] ^= gf_mul[col[2]][0];
   state[2][2] ^= gf_mul[col[3]][1];
   state[3][2] = gf_mul[col[0]][1];
   state[3][2] ^= col[1];
   state[3][2] ^= col[2];
   state[3][2] ^= gf_mul[col[3]][0];
   // Column 4
   col[0] = state[0][3];
   col[1] = state[1][3];
   col[2] = state[2][3];
   col[3] = state[3][3];
   state[0][3] = gf_mul[col[0]][0];
   state[0][3] ^= gf_mul[col[1]][1];
   state[0][3] ^= col[2];
   state[0][3] ^= col[3];
   state[1][3] = col[0];
   state[1][3] ^= gf_mul[col[1]][0];
   state[1][3] ^= gf_mul[col[2]][1];
   state[1][3] ^= col[3];
   state[2][3] = col[0];
   state[2][3] ^= col[1];
   state[2][3] ^= gf_mul[col[2]][0];
   state[2][3] ^= gf_mul[col[3]][1];
   state[3][3] = gf_mul[col[0]][1];
   state[3][3] ^= col[1];
   state[3][3] ^= col[2];
   state[3][3] ^= gf_mul[col[3]][0];
}

[COLOR=royalblue][B]__host__ __device__[/B] void InvMixColumns(uchar state[][4])
{
   int idx;
   uchar col[4],t;
   // Column 1
   col[0] = state[0][0];
   col[1] = state[1][0];
   col[2] = state[2][0];
   col[3] = state[3][0];
   state[0][0] = gf_mul[col[0]][5];
   state[0][0] ^= gf_mul[col[1]][3];
   state[0][0] ^= gf_mul[col[2]][4];
   state[0][0] ^= gf_mul[col[3]][2];
   state[1][0] = gf_mul[col[0]][2];
   state[1][0] ^= gf_mul[col[1]][5];
   state[1][0] ^= gf_mul[col[2]][3];
   state[1][0] ^= gf_mul[col[3]][4];
   state[2][0] = gf_mul[col[0]][4];
   state[2][0] ^= gf_mul[col[1]][2];
   state[2][0] ^= gf_mul[col[2]][5];
   state[2][0] ^= gf_mul[col[3]][3];
   state[3][0] = gf_mul[col[0]][3];
   state[3][0] ^= gf_mul[col[1]][4];
   state[3][0] ^= gf_mul[col[2]][2];
   state[3][0] ^= gf_mul[col[3]][5];
   // Column 2
   col[0] = state[0][1];
   col[1] = state[1][1];
   col[2] = state[2][1];
   col[3] = state[3][1];
   state[0][1] = gf_mul[col[0]][5];
   state[0][1] ^= gf_mul[col[1]][3];
   state[0][1] ^= gf_mul[col[2]][4];
   state[0][1] ^= gf_mul[col[3]][2];
   state[1][1] = gf_mul[col[0]][2];
   state[1][1] ^= gf_mul[col[1]][5];
   state[1][1] ^= gf_mul[col[2]][3];
   state[1][1] ^= gf_mul[col[3]][4];
   state[2][1] = gf_mul[col[0]][4];
   state[2][1] ^= gf_mul[col[1]][2];
   state[2][1] ^= gf_mul[col[2]][5];
   state[2][1] ^= gf_mul[col[3]][3];
   state[3][1] = gf_mul[col[0]][3];
   state[3][1] ^= gf_mul[col[1]][4];
   state[3][1] ^= gf_mul[col[2]][2];
   state[3][1] ^= gf_mul[col[3]][5];
   // Column 3
   col[0] = state[0][2];
   col[1] = state[1][2];
   col[2] = state[2][2];
   col[3] = state[3][2];
   state[0][2] = gf_mul[col[0]][5];
   state[0][2] ^= gf_mul[col[1]][3];
   state[0][2] ^= gf_mul[col[2]][4];
   state[0][2] ^= gf_mul[col[3]][2];
   state[1][2] = gf_mul[col[0]][2];
   state[1][2] ^= gf_mul[col[1]][5];
   state[1][2] ^= gf_mul[col[2]][3];
   state[1][2] ^= gf_mul[col[3]][4];
   state[2][2] = gf_mul[col[0]][4];
   state[2][2] ^= gf_mul[col[1]][2];
   state[2][2] ^= gf_mul[col[2]][5];
   state[2][2] ^= gf_mul[col[3]][3];
   state[3][2] = gf_mul[col[0]][3];
   state[3][2] ^= gf_mul[col[1]][4];
   state[3][2] ^= gf_mul[col[2]][2];
   state[3][2] ^= gf_mul[col[3]][5];
   // Column 4
   col[0] = state[0][3];
   col[1] = state[1][3];
   col[2] = state[2][3];
   col[3] = state[3][3];
   state[0][3] = gf_mul[col[0]][5];
   state[0][3] ^= gf_mul[col[1]][3];
   state[0][3] ^= gf_mul[col[2]][4];
   state[0][3] ^= gf_mul[col[3]][2];
   state[1][3] = gf_mul[col[0]][2];
   state[1][3] ^= gf_mul[col[1]][5];
   state[1][3] ^= gf_mul[col[2]][3];
   state[1][3] ^= gf_mul[col[3]][4];
   state[2][3] = gf_mul[col[0]][4];
   state[2][3] ^= gf_mul[col[1]][2];
   state[2][3] ^= gf_mul[col[2]][5];
   state[2][3] ^= gf_mul[col[3]][3];
   state[3][3] = gf_mul[col[0]][3];
   state[3][3] ^= gf_mul[col[1]][4];
   state[3][3] ^= gf_mul[col[2]][2];
   state[3][3] ^= gf_mul[col[3]][5];
}

/********************
** DEBUGGING FUNCTIONS
********************/

// This prints the "state" grid as a linear hex string
void printstate(uchar state[][4])
{
   int idx,idx2;
   for (idx=0; idx < 4; idx++)
      for (idx2=0; idx2 < 4; idx2++)
         printf("%02x",state[idx2][idx]);
   puts("");
}

// This prints the key (4 consecutive ints) used for a given round as a linear hex string.
void print_rnd_key(uint key[])
{
   int idx;
   for (idx=0; idx < 4; idx++)
      printf("%08x",key[idx]);
   puts("");
}

/********************
** KEY EXPANSION
********************/

// Performs the SubWord substitution for KeyExpansion. Each byte in the supplied integer
// is looked up in the substitution box and replaced by its corresponding value.
uint SubWord(uint word)
{
   unsigned int result;

   result = (int)aes_sbox[(word >> 4) & 0x0000000F][word & 0x0000000F];
   result += (int)aes_sbox[(word >> 12) & 0x0000000F][(word >> 8) & 0x0000000F] << 8;
   result += (int)aes_sbox[(word >> 20) & 0x0000000F][(word >> 16) & 0x0000000F] << 16;
   result += (int)aes_sbox[(word >> 28) & 0x0000000F][(word >> 24) & 0x0000000F] << 24;
   return(result);
}

// Performs the RotWord function for KeyExpansion. The first byte in the integer is rotated
// to the end.
#define KE_ROTWORD(x) ( ((x) << 8) | ((x) >> 24) )

// Performs the action of generating the keys that will be used in every round of
// encryption. "key" is the user-supplied input key, "w" is the output key schedule,
// "keysize" is the length in bits of "key", must be 128, 192, or 256.
void KeyExpansion(uchar key[], uint w[], int keysize)
{
   int Nb=4,Nr,Nk,idx;
   uint temp,Rcon[]={0x01000000,0x02000000,0x04000000,0x08000000,0x10000000,0x20000000,
                     0x40000000,0x80000000,0x1b000000,0x36000000,0x6c000000,0xd8000000,
                     0xab000000,0x4d000000,0x9a000000};
   switch (keysize) {
      case 128: Nr = 10; Nk = 4; break;
      case 192: Nr = 12; Nk = 6; break;
      case 256: Nr = 14; Nk = 8; break;
      default: return;
   }

   for (idx=0; idx < Nk; ++idx) {
      w[idx] = ((key[4 * idx]) << 24) | ((key[4 * idx + 1]) << 16) |
               ((key[4 * idx + 2]) << 8) | ((key[4 * idx + 3]));
   }

   for (idx = Nk; idx < Nb * (Nr+1); ++idx) {
      temp = w[idx - 1];
      if ((idx % Nk) == 0)
         temp = SubWord(KE_ROTWORD(temp)) ^ Rcon[(idx-1)/Nk];
      else if (Nk > 6 && (idx % Nk) == 4)
         temp = SubWord(temp);
      w[idx] = w[idx-Nk] ^ temp;
   }
}

/********************
** AES (En/De)Crypt
********************/

// "in" is the block of 16 sequencial bytes that is to be encrypted. "out" is the encrypted
// sequencial output. "key" is an array consisting of the KEY value that was generated
// using KeySchedule() previously. "keysize" MUST be 128, 192, 256 in size.
[COLOR=royalblue][B]__device__[/B] void aes_encrypt(uchar in[], uchar out[], uint key[], int keysize)
{
   uchar state[4][4];
   // Copy input array (should be 16 bytes long) to a matrix (sequential bytes are ordered
   // by row, not col) called "state" for processing.
   // *** Implementation note: The official AES documentation references the state by
   // column, then row. Accessing an element in C requires row then column. Thus, all state
   // references in AES must have the column and row indexes reversed for C implementation.
   state[0][0] = in[0];
   state[1][0] = in[1];
   state[2][0] = in[2];
   state[3][0] = in[3];
   state[0][1] = in[4];
   state[1][1] = in[5];
   state[2][1] = in[6];
   state[3][1] = in[7];
   state[0][2] = in[8];
   state[1][2] = in[9];
   state[2][2] = in[10];
   state[3][2] = in[11];
   state[0][3] = in[12];
   state[1][3] = in[13];
   state[2][3] = in[14];
   state[3][3] = in[15];

   // Perform the necessary number of rounds. The round key is added first.
   // The last round does not perform the MixColumns step.
   AddRoundKey(state,&key[0]);
   SubBytes(state); ShiftRows(state); MixColumns(state); AddRoundKey(state,&key[4]);
   SubBytes(state); ShiftRows(state); MixColumns(state); AddRoundKey(state,&key[8]);
   SubBytes(state); ShiftRows(state); MixColumns(state); AddRoundKey(state,&key[12]);
   SubBytes(state); ShiftRows(state); MixColumns(state); AddRoundKey(state,&key[16]);
   SubBytes(state); ShiftRows(state); MixColumns(state); AddRoundKey(state,&key[20]);
   SubBytes(state); ShiftRows(state); MixColumns(state); AddRoundKey(state,&key[24]);
   SubBytes(state); ShiftRows(state); MixColumns(state); AddRoundKey(state,&key[28]);
   SubBytes(state); ShiftRows(state); MixColumns(state); AddRoundKey(state,&key[32]);
   SubBytes(state); ShiftRows(state); MixColumns(state); AddRoundKey(state,&key[36]);
   if (keysize != 128) {
      SubBytes(state); ShiftRows(state); MixColumns(state); AddRoundKey(state,&key[40]);
      SubBytes(state); ShiftRows(state); MixColumns(state); AddRoundKey(state,&key[44]);
      if (keysize != 192) {
         SubBytes(state); ShiftRows(state); MixColumns(state); AddRoundKey(state,&key[48]);
         SubBytes(state); ShiftRows(state); MixColumns(state); AddRoundKey(state,&key[52]);
         SubBytes(state); ShiftRows(state); AddRoundKey(state,&key[56]);
      }
      else {
         SubBytes(state); ShiftRows(state); AddRoundKey(state,&key[48]);
      }
   }
   else {
      SubBytes(state); ShiftRows(state); AddRoundKey(state,&key[40]);
   }

   // Copy the state to the output array
   out[0] = state[0][0];
   out[1] = state[1][0];
   out[2] = state[2][0];
   out[3] = state[3][0];
   out[4] = state[0][1];
   out[5] = state[1][1];
   out[6] = state[2][1];
   out[7] = state[3][1];
   out[8] = state[0][2];
   out[9] = state[1][2];
   out[10] = state[2][2];
   out[11] = state[3][2];
   out[12] = state[0][3];
   out[13] = state[1][3];
   out[14] = state[2][3];
   out[15] = state[3][3];
}

[COLOR=royalblue][B]__device__[/B] void aes_decrypt(uchar in[], uchar out[], uint key[], int keysize)
{
   uchar state[4][4];
   // Copy the input to the state.
   state[0][0] = in[0];
   state[1][0] = in[1];
   state[2][0] = in[2];
   state[3][0] = in[3];
   state[0][1] = in[4];
   state[1][1] = in[5];
   state[2][1] = in[6];
   state[3][1] = in[7];
   state[0][2] = in[8];
   state[1][2] = in[9];
   state[2][2] = in[10];
   state[3][2] = in[11];
   state[0][3] = in[12];
   state[1][3] = in[13];
   state[2][3] = in[14];
   state[3][3] = in[15];

   // Perform the necessary number of rounds. The round key is added first.
   // The last round does not perform the MixColumns step.
   if (keysize > 128) {
      if (keysize > 192) {
         AddRoundKey(state,&key[56]);
         InvShiftRows(state);InvSubBytes(state);AddRoundKey(state,&key[52]);InvMixColumns(state);
         InvShiftRows(state);InvSubBytes(state);AddRoundKey(state,&key[48]);InvMixColumns(state);
      }
      else {
         AddRoundKey(state,&key[48]);
      }
      InvShiftRows(state);InvSubBytes(state);AddRoundKey(state,&key[44]);InvMixColumns(state);
      InvShiftRows(state);InvSubBytes(state);AddRoundKey(state,&key[40]);InvMixColumns(state);
   }
   else {
      AddRoundKey(state,&key[40]);
   }
   InvShiftRows(state);InvSubBytes(state);AddRoundKey(state,&key[36]);InvMixColumns(state);
   InvShiftRows(state);InvSubBytes(state);AddRoundKey(state,&key[32]);InvMixColumns(state);
   InvShiftRows(state);InvSubBytes(state);AddRoundKey(state,&key[28]);InvMixColumns(state);
   InvShiftRows(state);InvSubBytes(state);AddRoundKey(state,&key[24]);InvMixColumns(state);
   InvShiftRows(state);InvSubBytes(state);AddRoundKey(state,&key[20]);InvMixColumns(state);
   InvShiftRows(state);InvSubBytes(state);AddRoundKey(state,&key[16]);InvMixColumns(state);
   InvShiftRows(state);InvSubBytes(state);AddRoundKey(state,&key[12]);InvMixColumns(state);
   InvShiftRows(state);InvSubBytes(state);AddRoundKey(state,&key[8]);InvMixColumns(state);
   InvShiftRows(state);InvSubBytes(state);AddRoundKey(state,&key[4]);InvMixColumns(state);
   InvShiftRows(state);InvSubBytes(state);AddRoundKey(state,&key[0]);

   // Copy the state to the output array
   out[0] = state[0][0];
   out[1] = state[1][0];
   out[2] = state[2][0];
   out[3] = state[3][0];
   out[4] = state[0][1];
   out[5] = state[1][1];
   out[6] = state[2][1];
   out[7] = state[3][1];
   out[8] = state[0][2];
   out[9] = state[1][2];
   out[10] = state[2][2];
   out[11] = state[3][2];
   out[12] = state[0][3];
   out[13] = state[1][3];
   out[14] = state[2][3];
   out[15] = state[3][3];
}

[COLOR=royalblue][B]__global__ void aes_enc(uchar in[], uchar out[], uint key[], int keysize) {
    int b = blockIdx.x*blockDim.x + threadIdx.x;
    aes_encrypt(in + 16*b, out + 16*b, key, keysize);
}

__global__ void aes_dec(uchar in[], uchar out[], uint key[], int keysize) {
    int b = blockIdx.x*blockDim.x + threadIdx.x;
    aes_decrypt(in + 16*b, out + 16*b, key, keysize);
}

inline void HandleErrorImpl(cudaError error, const char* file, int line) {
    if (error != cudaSuccess) {
        printf("%s: %d %s", file, line, cudaGetErrorString(error));
        exit(1);
    }
}

int main(void) {
    char *key = "meingeheimespasswort";
    int threads = 256;
    int blocks = 25600;
    int keysize = strlen(key);

    uchar *in;
    HandleError(cudaMalloc(&in, 16*threads*blocks));
    HandleError(cudaMemset(in, 0, 16*threads*blocks));

    uchar *out;
    HandleError(cudaMalloc(&out, 16*threads*blocks));

    char *test1 = (char*)malloc(16*threads*blocks);
    HandleError(cudaMemcpy(test1, in, 16*threads*blocks, cudaMemcpyDeviceToHost));

    printf("First 16 bytes of input data: ");
    for (int i=0; i<16; i++) {
        printf("%d, ", test1[i]);
    }

    cudaEvent_t start, stop;
    HandleError(cudaEventCreate(&start));
    HandleError(cudaEventCreate(&stop));
    HandleError(cudaEventRecord( start, 0 ));

    aes_enc<<<blocks,threads>>>(in, out, (uint*)key, keysize);
    aes_dec<<<blocks,threads>>>(out, in, (uint*)key, keysize);

    HandleError(cudaGetLastError());

    HandleError(cudaEventRecord( stop, 0 ));
    HandleError(cudaEventSynchronize( stop ));
    float elapsedTime;
    HandleError(cudaEventElapsedTime( &elapsedTime, start, stop ));

    printf("\nPerformance: %.6f MB/sec\n", 2*((16*threads*blocks)/1048576)/(elapsedTime/1000));

    HandleError(cudaEventDestroy( start ));
    HandleError(cudaEventDestroy( stop ));

    char *test2 = (char*)malloc(16*threads*blocks);
    HandleError(cudaMemcpy(test2, out, 16*threads*blocks, cudaMemcpyDeviceToHost));

    printf("After decryption: ");
    for (int i=0; i<16; i++) {
        printf("%d, ", test2[i]);
    }

    free(test1);
    free(test2);

    HandleError(cudaFree(in));
    HandleError(cudaFree(out));

    return 0;
}[/B]
^^ Stimmen meine ganzen eingefügten __host__ __device__? Ich musste die alle einfügen, damit der Code überhaupt ohne Errors startet, aber mir kommt das dennoch leicht komisch vor.

Jetzt müsste ich nur noch bei Twofish und AES die launch failure wegkriegen. Läuft AES, so wie er hier ist, auf deiner GTX 560 Ti?
 
MARS

Habe jetzt zu guter letzt auch noch einen MARS C Code nach CUDA portiert, ganz nach unserem Schema:
Code:
/* This is an independent implementation of the encryption algorithm:   */

/*                                                                      */

/*         MARS by a team at IBM,                                        */

/*                                                                      */

/* which is a candidate algorithm in the Advanced Encryption Standard   */

/* programme of the US National Institute of Standards and Technology.  */

/* Copyright in this implementation is held by Dr B R Gladman. The MARS */

/* algorithm is covered by a pending patent application owned by IBM,   */

/* who intend to offer a royalty free license under any issued patent   */

/* that results from such application if MARS is selected as the AES    */

/* algorithm.  In the interim, you may evaluate the MARS algorithm for  */

/* your personal, lawful, non-profit purposes as an end user.           */

/*                                                                      */

/* The header above modified on June 6th 1999.                          */

/* Dr Brian Gladman (gladman@seven77.demon.co.uk) 14th January 1999     */



/* Timing data for MARS (mars.c)



128 bit key:

Key Setup:    4316 cycles

Encrypt:       369 cycles =    69.4 mbits/sec

Decrypt:       376 cycles =    68.1 mbits/sec

Mean:          373 cycles =    68.7 mbits/sec



192 bit key:

Key Setup:    4377 cycles

Encrypt:       373 cycles =    68.6 mbits/sec

Decrypt:       379 cycles =    67.5 mbits/sec

Mean:          376 cycles =    68.1 mbits/sec



256 bit key:

Key Setup:    4340 cycles

Encrypt:       369 cycles =    69.4 mbits/sec

Decrypt:       376 cycles =    68.1 mbits/sec

Mean:          373 cycles =    68.7 mbits/sec



*/



#include "std_defs.h"
[COLOR=royalblue][B]#include <stdio.h>[/B]


static char *alg_name[] = { "mars", "mars.c", "mars" };



char **cipher_name()

{

    return alg_name;

}


[COLOR=royalblue][B]
__device__[/B] static u4byte s_box[] =

{

    0x09d0c479, 0x28c8ffe0, 0x84aa6c39, 0x9dad7287, /* 0x000    */

    0x7dff9be3, 0xd4268361, 0xc96da1d4, 0x7974cc93,

    0x85d0582e, 0x2a4b5705, 0x1ca16a62, 0xc3bd279d,

    0x0f1f25e5, 0x5160372f, 0xc695c1fb, 0x4d7ff1e4,

    0xae5f6bf4, 0x0d72ee46, 0xff23de8a, 0xb1cf8e83, /* 0x010    */

    0xf14902e2, 0x3e981e42, 0x8bf53eb6, 0x7f4bf8ac,

    0x83631f83, 0x25970205, 0x76afe784, 0x3a7931d4,

    0x4f846450, 0x5c64c3f6, 0x210a5f18, 0xc6986a26,

    0x28f4e826, 0x3a60a81c, 0xd340a664, 0x7ea820c4, /* 0x020    */

    0x526687c5, 0x7eddd12b, 0x32a11d1d, 0x9c9ef086,

    0x80f6e831, 0xab6f04ad, 0x56fb9b53, 0x8b2e095c,

    0xb68556ae, 0xd2250b0d, 0x294a7721, 0xe21fb253,

    0xae136749, 0xe82aae86, 0x93365104, 0x99404a66, /* 0x030    */

    0x78a784dc, 0xb69ba84b, 0x04046793, 0x23db5c1e,

    0x46cae1d6, 0x2fe28134, 0x5a223942, 0x1863cd5b,

    0xc190c6e3, 0x07dfb846, 0x6eb88816, 0x2d0dcc4a,

    0xa4ccae59, 0x3798670d, 0xcbfa9493, 0x4f481d45, /* 0x040    */

    0xeafc8ca8, 0xdb1129d6, 0xb0449e20, 0x0f5407fb,

    0x6167d9a8, 0xd1f45763, 0x4daa96c3, 0x3bec5958,

    0xababa014, 0xb6ccd201, 0x38d6279f, 0x02682215,

    0x8f376cd5, 0x092c237e, 0xbfc56593, 0x32889d2c, /* 0x050    */

    0x854b3e95, 0x05bb9b43, 0x7dcd5dcd, 0xa02e926c,

    0xfae527e5, 0x36a1c330, 0x3412e1ae, 0xf257f462,

    0x3c4f1d71, 0x30a2e809, 0x68e5f551, 0x9c61ba44,

    0x5ded0ab8, 0x75ce09c8, 0x9654f93e, 0x698c0cca, /* 0x060    */

    0x243cb3e4, 0x2b062b97, 0x0f3b8d9e, 0x00e050df,

    0xfc5d6166, 0xe35f9288, 0xc079550d, 0x0591aee8,

    0x8e531e74, 0x75fe3578, 0x2f6d829a, 0xf60b21ae,

    0x95e8eb8d, 0x6699486b, 0x901d7d9b, 0xfd6d6e31, /* 0x070    */

    0x1090acef, 0xe0670dd8, 0xdab2e692, 0xcd6d4365,

    0xe5393514, 0x3af345f0, 0x6241fc4d, 0x460da3a3,

    0x7bcf3729, 0x8bf1d1e0, 0x14aac070, 0x1587ed55,

    0x3afd7d3e, 0xd2f29e01, 0x29a9d1f6, 0xefb10c53, /* 0x080    */

    0xcf3b870f, 0xb414935c, 0x664465ed, 0x024acac7,

    0x59a744c1, 0x1d2936a7, 0xdc580aa6, 0xcf574ca8,

    0x040a7a10, 0x6cd81807, 0x8a98be4c, 0xaccea063,

    0xc33e92b5, 0xd1e0e03d, 0xb322517e, 0x2092bd13, /* 0x090    */

    0x386b2c4a, 0x52e8dd58, 0x58656dfb, 0x50820371,

    0x41811896, 0xe337ef7e, 0xd39fb119, 0xc97f0df6,

    0x68fea01b, 0xa150a6e5, 0x55258962, 0xeb6ff41b,

    0xd7c9cd7a, 0xa619cd9e, 0xbcf09576, 0x2672c073, /* 0x0a0    */

    0xf003fb3c, 0x4ab7a50b, 0x1484126a, 0x487ba9b1,

    0xa64fc9c6, 0xf6957d49, 0x38b06a75, 0xdd805fcd,

    0x63d094cf, 0xf51c999e, 0x1aa4d343, 0xb8495294,

    0xce9f8e99, 0xbffcd770, 0xc7c275cc, 0x378453a7, /* 0x0b0    */

    0x7b21be33, 0x397f41bd, 0x4e94d131, 0x92cc1f98,

    0x5915ea51, 0x99f861b7, 0xc9980a88, 0x1d74fd5f,

    0xb0a495f8, 0x614deed0, 0xb5778eea, 0x5941792d,

    0xfa90c1f8, 0x33f824b4, 0xc4965372, 0x3ff6d550, /* 0x0c0    */

    0x4ca5fec0, 0x8630e964, 0x5b3fbbd6, 0x7da26a48,

    0xb203231a, 0x04297514, 0x2d639306, 0x2eb13149,

    0x16a45272, 0x532459a0, 0x8e5f4872, 0xf966c7d9,

    0x07128dc0, 0x0d44db62, 0xafc8d52d, 0x06316131, /* 0x0d0    */

    0xd838e7ce, 0x1bc41d00, 0x3a2e8c0f, 0xea83837e,

    0xb984737d, 0x13ba4891, 0xc4f8b949, 0xa6d6acb3,

    0xa215cdce, 0x8359838b, 0x6bd1aa31, 0xf579dd52,

    0x21b93f93, 0xf5176781, 0x187dfdde, 0xe94aeb76, /* 0x0e0    */

    0x2b38fd54, 0x431de1da, 0xab394825, 0x9ad3048f,

    0xdfea32aa, 0x659473e3, 0x623f7863, 0xf3346c59,

    0xab3ab685, 0x3346a90b, 0x6b56443e, 0xc6de01f8,

    0x8d421fc0, 0x9b0ed10c, 0x88f1a1e9, 0x54c1f029, /* 0x0f0    */

    0x7dead57b, 0x8d7ba426, 0x4cf5178a, 0x551a7cca,

    0x1a9a5f08, 0xfcd651b9, 0x25605182, 0xe11fc6c3,

    0xb6fd9676, 0x337b3027, 0xb7c8eb14, 0x9e5fd030,



    0x6b57e354, 0xad913cf7, 0x7e16688d, 0x58872a69, /* 0x100    */

    0x2c2fc7df, 0xe389ccc6, 0x30738df1, 0x0824a734,

    0xe1797a8b, 0xa4a8d57b, 0x5b5d193b, 0xc8a8309b,

    0x73f9a978, 0x73398d32, 0x0f59573e, 0xe9df2b03,

    0xe8a5b6c8, 0x848d0704, 0x98df93c2, 0x720a1dc3, /* 0x110    */

    0x684f259a, 0x943ba848, 0xa6370152, 0x863b5ea3,

    0xd17b978b, 0x6d9b58ef, 0x0a700dd4, 0xa73d36bf,

    0x8e6a0829, 0x8695bc14, 0xe35b3447, 0x933ac568,

    0x8894b022, 0x2f511c27, 0xddfbcc3c, 0x006662b6, /* 0x120    */

    0x117c83fe, 0x4e12b414, 0xc2bca766, 0x3a2fec10,

    0xf4562420, 0x55792e2a, 0x46f5d857, 0xceda25ce,

    0xc3601d3b, 0x6c00ab46, 0xefac9c28, 0xb3c35047,

    0x611dfee3, 0x257c3207, 0xfdd58482, 0x3b14d84f, /* 0x130    */

    0x23becb64, 0xa075f3a3, 0x088f8ead, 0x07adf158,

    0x7796943c, 0xfacabf3d, 0xc09730cd, 0xf7679969,

    0xda44e9ed, 0x2c854c12, 0x35935fa3, 0x2f057d9f,

    0x690624f8, 0x1cb0bafd, 0x7b0dbdc6, 0x810f23bb, /* 0x140    */

    0xfa929a1a, 0x6d969a17, 0x6742979b, 0x74ac7d05,

    0x010e65c4, 0x86a3d963, 0xf907b5a0, 0xd0042bd3,

    0x158d7d03, 0x287a8255, 0xbba8366f, 0x096edc33,

    0x21916a7b, 0x77b56b86, 0x951622f9, 0xa6c5e650, /* 0x150    */

    0x8cea17d1, 0xcd8c62bc, 0xa3d63433, 0x358a68fd,

    0x0f9b9d3c, 0xd6aa295b, 0xfe33384a, 0xc000738e,

    0xcd67eb2f, 0xe2eb6dc2, 0x97338b02, 0x06c9f246,

    0x419cf1ad, 0x2b83c045, 0x3723f18a, 0xcb5b3089, /* 0x160    */

    0x160bead7, 0x5d494656, 0x35f8a74b, 0x1e4e6c9e,

    0x000399bd, 0x67466880, 0xb4174831, 0xacf423b2,

    0xca815ab3, 0x5a6395e7, 0x302a67c5, 0x8bdb446b,

    0x108f8fa4, 0x10223eda, 0x92b8b48b, 0x7f38d0ee, /* 0x170    */

    0xab2701d4, 0x0262d415, 0xaf224a30, 0xb3d88aba,

    0xf8b2c3af, 0xdaf7ef70, 0xcc97d3b7, 0xe9614b6c,

    0x2baebff4, 0x70f687cf, 0x386c9156, 0xce092ee5,

    0x01e87da6, 0x6ce91e6a, 0xbb7bcc84, 0xc7922c20, /* 0x180    */

    0x9d3b71fd, 0x060e41c6, 0xd7590f15, 0x4e03bb47,

    0x183c198e, 0x63eeb240, 0x2ddbf49a, 0x6d5cba54,

    0x923750af, 0xf9e14236, 0x7838162b, 0x59726c72,

    0x81b66760, 0xbb2926c1, 0x48a0ce0d, 0xa6c0496d, /* 0x190    */

    0xad43507b, 0x718d496a, 0x9df057af, 0x44b1bde6,

    0x054356dc, 0xde7ced35, 0xd51a138b, 0x62088cc9,

    0x35830311, 0xc96efca2, 0x686f86ec, 0x8e77cb68,

    0x63e1d6b8, 0xc80f9778, 0x79c491fd, 0x1b4c67f2, /* 0x1a0    */

    0x72698d7d, 0x5e368c31, 0xf7d95e2e, 0xa1d3493f,

    0xdcd9433e, 0x896f1552, 0x4bc4ca7a, 0xa6d1baf4,

    0xa5a96dcc, 0x0bef8b46, 0xa169fda7, 0x74df40b7,

    0x4e208804, 0x9a756607, 0x038e87c8, 0x20211e44, /* 0x1b0    */

    0x8b7ad4bf, 0xc6403f35, 0x1848e36d, 0x80bdb038,

    0x1e62891c, 0x643d2107, 0xbf04d6f8, 0x21092c8c,

    0xf644f389, 0x0778404e, 0x7b78adb8, 0xa2c52d53,

    0x42157abe, 0xa2253e2e, 0x7bf3f4ae, 0x80f594f9, /* 0x1c0    */

    0x953194e7, 0x77eb92ed, 0xb3816930, 0xda8d9336,

    0xbf447469, 0xf26d9483, 0xee6faed5, 0x71371235,

    0xde425f73, 0xb4e59f43, 0x7dbe2d4e, 0x2d37b185,

    0x49dc9a63, 0x98c39d98, 0x1301c9a2, 0x389b1bbf, /* 0x1d0    */

    0x0c18588d, 0xa421c1ba, 0x7aa3865c, 0x71e08558,

    0x3c5cfcaa, 0x7d239ca4, 0x0297d9dd, 0xd7dc2830,

    0x4b37802b, 0x7428ab54, 0xaeee0347, 0x4b3fbb85,

    0x692f2f08, 0x134e578e, 0x36d9e0bf, 0xae8b5fcf, /* 0x1e0    */

    0xedb93ecf, 0x2b27248e, 0x170eb1ef, 0x7dc57fd6,

    0x1e760f16, 0xb1136601, 0x864e1b9b, 0xd7ea7319,

    0x3ab871bd, 0xcfa4d76f, 0xe31bd782, 0x0dbeb469,

    0xabb96061, 0x5370f85d, 0xffb07e37, 0xda30d0fb, /* 0x1f0    */

    0xebc977b6, 0x0b98b40f, 0x3a4d0fe6, 0xdf4fc26b,

    0x159cf22a, 0xc298d6e2, 0x2b78ef6a, 0x61a94ac0,

    0xab561187, 0x14eea0f0, 0xdf0d4164, 0x19af70ee

};



static u4byte vk[47] =

{

    0x09d0c479, 0x28c8ffe0, 0x84aa6c39, 0x9dad7287, 0x7dff9be3, 0xd4268361,

    0xc96da1d4

};



[COLOR=royalblue][B]__device__[/B] static u4byte   l_key[40];
[COLOR=royalblue][B]
#define HandleError(x) HandleErrorImpl(x, __FILE__, __LINE__)[/B]
#define f_mix(a,b,c,d)                  \
        r = rotr(a, 8);                 \
        b ^= s_box[a & 255];            \
        b += s_box[(r & 255) + 256];    \
        r = rotr(a, 16);                \
        a  = rotr(a, 24);               \
        c += s_box[r & 255];            \
        d ^= s_box[(a & 255) + 256];



#define b_mix(a,b,c,d)                  \
        r = rotl(a, 8);                 \
        b ^= s_box[(a & 255) + 256];    \
        c -= s_box[r & 255];            \
        r = rotl(a, 16);                \
        a  = rotl(a, 24);               \
        d -= s_box[(r & 255) + 256];    \
        d ^= s_box[a & 255];



#define f_ktr(a,b,c,d,i)    \
    m = a + l_key[i];       \
    a = rotl(a, 13);        \
    r = a * l_key[i + 1];   \
    l = s_box[m & 511];     \
    r = rotl(r, 5);         \
    c += rotl(m, r);        \
    l ^= r;                 \
    r = rotl(r, 5);         \
    l ^= r;                 \
    d ^= r;                 \
    b += rotl(l, r);



#define r_ktr(a,b,c,d,i)    \
    r = a * l_key[i + 1];   \
    a = rotr(a, 13);        \
    m = a + l_key[i];       \
    l = s_box[m & 511];     \
    r = rotl(r, 5);         \
    l ^= r;                 \
    c -= rotl(m, r);        \
    r = rotl(r, 5);         \
    l ^= r;                 \
    d ^= r;                 \
    b -= rotl(l, r);



/* For a 32 bit word (x) generate a mask (m) such that a bit in */

/* m is set to 1 if and only if the corresponding bit in x is:  */

/*                                                              */

/* 1. in a sequence of 10 or more adjacent '0' bits             */

/* 2. in a sequence of 10 or more adjacent '1' bits             */

/* 3. but is not either endpoint of such a sequence unless such */

/*    an endpoint is at the top bit (bit 31) of a word and is   */

/*    in a sequence of '0' bits.                                */

/*                                                              */

/* The only situation in which a sequence endpoint is included  */

/* in the mask is hence when the endpoint is at bit 31 and is   */

/* the endpoint of a sequence of '0' bits. My thanks go to Shai */

/* Halevi of IBM for the neat trick (which I missed) of finding */

/* the '0' and '1' sequences at the same time.                  */



u4byte gen_mask(u4byte x)

{   u4byte  m;



    /* if m{bn} stands for bit number bn of m, set m{bn} = 1 if */

    /* x{bn} == x{bn+1} for 0 <= bn <= 30.  That is, set a bit  */

    /* in m if the corresponding bit and the next higher bit in */

    /* x are equal in value (set m{31} = 0).                    */



    m = (~x ^ (x >> 1)) & 0x7fffffff;



    /* Sequences of 9 '1' bits in m now correspond to sequences */

    /* of 10 '0's or 10 '1' bits in x.  Shift and 'and' bits in */

    /* m to find sequences of 9 or more '1' bits.   As a result */

    /* bits in m are set if they are at the bottom of sequences */

    /* of 10 adjacent '0's or 10 adjacent '1's in x.            */



    m &= (m >> 1) & (m >> 2); m &= (m >> 3) & (m >> 6);



    if(!m)  /* return if mask is empty - no key fixing needed   */

            /* is this early return worthwhile?                 */

        return 0;



    /* We need the internal bits in each continuous sequence of */

    /* matching bits (that is the bits less the two endpoints). */

    /* We thus propagate each set bit into the 8 internal bits  */

    /* that it represents, starting 1 left and finsihing 8 left */

    /* of its position.                                         */



    m <<= 1; m |= (m << 1); m |= (m << 2); m |= (m << 4);



    /* m is now correct except for the odd behaviour of bit 31, */

    /* that is, it will be set if it is in a sequence of 10 or  */

    /* more '0's and clear otherwise.                           */



    m |= (m << 1) & ~x & 0x80000000;



    return m & 0xfffffffc;

};



/* My thanks to Louis Granboulan for spotting an error in the   */

/* previous version of set_key.                                 */



u4byte *set_key(const u4byte in_key[], const u4byte key_len)

{   u4byte  i, j, m, w;



    m = key_len / 32 - 1;



    for(i = j = 0; i < 39; ++i)

    {

      vk[i + 7] = rotl(vk[i] ^ vk[i + 5], 3) ^ in_key[j] ^ i;



      j = (j == m ? 0 : j + 1);

    }



    vk[46] = key_len / 32;



    for(j = 0; j < 7; ++j)

    {

         for(i = 1; i < 40; ++i)



            vk[i + 7] = rotl(vk[i + 7] + s_box[vk[i + 6] & 511], 9);



        vk[7] = rotl(vk[7] + s_box[vk[46] & 511], 9);

    }



    for(i = j = 0; i < 40; ++i)

    {

        l_key[j] = vk[i + 7];



        j = (j < 33 ? j + 7 : j - 33);

    }



    for(i = 5; i < 37; i += 2)

    {

        w = l_key[i] | 3;



        if(m = gen_mask(w))



            w ^= (rotl(s_box[265 + (l_key[i] & 3)], l_key[i + 3] & 31) & m);



        l_key[i] = w;

    }



    return l_key;

};



[COLOR=royalblue][B]__device__[/B] void encrypt(const u4byte in_blk[4], u4byte out_blk[4])

{   u4byte  a, b, c, d, l, m, r;



    a = in_blk[0] + l_key[0]; b = in_blk[1] + l_key[1];

    c = in_blk[2] + l_key[2]; d = in_blk[3] + l_key[3];



    f_mix(a,b,c,d); a += d;

    f_mix(b,c,d,a); b += c;

    f_mix(c,d,a,b);

    f_mix(d,a,b,c);

    f_mix(a,b,c,d); a += d;

    f_mix(b,c,d,a); b += c;

    f_mix(c,d,a,b);

    f_mix(d,a,b,c);



    f_ktr(a,b,c,d, 4); f_ktr(b,c,d,a, 6); f_ktr(c,d,a,b, 8); f_ktr(d,a,b,c,10);

    f_ktr(a,b,c,d,12); f_ktr(b,c,d,a,14); f_ktr(c,d,a,b,16); f_ktr(d,a,b,c,18);

    f_ktr(a,d,c,b,20); f_ktr(b,a,d,c,22); f_ktr(c,b,a,d,24); f_ktr(d,c,b,a,26);

    f_ktr(a,d,c,b,28); f_ktr(b,a,d,c,30); f_ktr(c,b,a,d,32); f_ktr(d,c,b,a,34);



    b_mix(a,b,c,d);

    b_mix(b,c,d,a); c -= b;

    b_mix(c,d,a,b); d -= a;

    b_mix(d,a,b,c);

    b_mix(a,b,c,d);

    b_mix(b,c,d,a); c -= b;

    b_mix(c,d,a,b); d -= a;

    b_mix(d,a,b,c);



    out_blk[0] = a - l_key[36]; out_blk[1] = b - l_key[37];

    out_blk[2] = c - l_key[38]; out_blk[3] = d - l_key[39];

};



[COLOR=royalblue][B]__device__[/B] void decrypt(const u4byte in_blk[4], u4byte out_blk[4])

{   u4byte  a, b, c, d, l, m, r;



    d = in_blk[0] + l_key[36]; c = in_blk[1] + l_key[37];

    b = in_blk[2] + l_key[38]; a = in_blk[3] + l_key[39];



    f_mix(a,b,c,d); a += d;

    f_mix(b,c,d,a); b += c;

    f_mix(c,d,a,b);

    f_mix(d,a,b,c);

    f_mix(a,b,c,d); a += d;

    f_mix(b,c,d,a); b += c;

    f_mix(c,d,a,b);

    f_mix(d,a,b,c);



    r_ktr(a,b,c,d,34); r_ktr(b,c,d,a,32); r_ktr(c,d,a,b,30); r_ktr(d,a,b,c,28);

    r_ktr(a,b,c,d,26); r_ktr(b,c,d,a,24); r_ktr(c,d,a,b,22); r_ktr(d,a,b,c,20);

    r_ktr(a,d,c,b,18); r_ktr(b,a,d,c,16); r_ktr(c,b,a,d,14); r_ktr(d,c,b,a,12);

    r_ktr(a,d,c,b,10); r_ktr(b,a,d,c, 8); r_ktr(c,b,a,d, 6); r_ktr(d,c,b,a, 4);



    b_mix(a,b,c,d);

    b_mix(b,c,d,a); c -= b;

    b_mix(c,d,a,b); d -= a;

    b_mix(d,a,b,c);

    b_mix(a,b,c,d);

    b_mix(b,c,d,a); c -= b;

    b_mix(c,d,a,b); d -= a;

    b_mix(d,a,b,c);



    out_blk[0] = d - l_key[0]; out_blk[1] = c - l_key[1];

    out_blk[2] = b - l_key[2]; out_blk[3] = a - l_key[3];

}
[COLOR=royalblue][B]
__global__ void mars_enc(const u4byte in_blk[4], u4byte out_blk[4]) {
    int b = blockIdx.x*blockDim.x + threadIdx.x;
    encrypt(in_blk + 4*b, out_blk + 4*b);
}

__global__ void mars_dec(const u4byte in_blk[4], u4byte out_blk[4]) {
    int b = blockIdx.x*blockDim.x + threadIdx.x;
    decrypt(in_blk + 4*b, out_blk + 4*b);
}

inline void HandleErrorImpl(cudaError error, const char* file, int line) {
    if (error != cudaSuccess) {
        printf("%s: %d %s", file, line, cudaGetErrorString(error));
        exit(1);
    }
}

int main(void) {
    char* key = "meingeheimespasswort";
    int threads = 256;
    int blocks = 25600;
    set_key((const u4byte*)key, strlen(key));

    u4byte* in_blk;
    HandleError(cudaMalloc(&in_blk, 16*threads*blocks));
    HandleError(cudaMemset(in_blk, 0, 16*threads*blocks));

    u4byte* out_blk;
    HandleError(cudaMalloc(&out_blk, 16*threads*blocks));

    char *test1 = (char*)malloc(16*threads*blocks);
    HandleError(cudaMemcpy(test1, in_blk, 16*threads*blocks, cudaMemcpyDeviceToHost));

    printf("First 16 bytes of input data: ");
    for (int i=0; i<16; i++) {
        printf("%d, ", test1[i]);
    }

    cudaEvent_t start, stop;
    HandleError(cudaEventCreate(&start));
    HandleError(cudaEventCreate(&stop));
    HandleError(cudaEventRecord( start, 0 ));

    mars_enc<<<blocks,threads>>>(in_blk, out_blk);
    mars_dec<<<blocks,threads>>>(out_blk, in_blk);

    HandleError(cudaGetLastError());

    HandleError(cudaEventRecord( stop, 0 ));
    HandleError(cudaEventSynchronize( stop ));
    float elapsedTime;
    HandleError(cudaEventElapsedTime( &elapsedTime, start, stop ));

    printf("\nPerformance: %.6f MB/sec\n", 2*((16*threads*blocks)/1048576)/(elapsedTime/1000));

    HandleError(cudaEventDestroy( start ));
    HandleError(cudaEventDestroy( stop ));

    char *test2 = (char*)malloc(16*threads*blocks);
    HandleError(cudaMemcpy(test2, in_blk, 16*threads*blocks, cudaMemcpyDeviceToHost));

    printf("After decryption: ");
    for (int i=0; i<16; i++) {
        printf("%d, ", test2[i]);
    }

    free(test1);
    free(test2);

    HandleError(cudaFree(in_blk));
    HandleError(cudaFree(out_blk));

    return 0;
}[/B]
Da der Original-Code von den selben Autoren zu sein schien wie Twofish, konnte ich nahezu alles fast 1:1 kopieren. Allerdings kriege ich auch in MARS den selben Fehler:

snapshot43.png

Habe ich also den Pointer-Fehler mitkopiert. Wenn wir ihn aber in einem der drei Codes finden, dürfte sich das ganze auch ganz leicht in den anderen beiden beheben lassen, weil's in Twofish, AES, und MARS wirklich der exakt selbe Fehler sein dürfte?!
 
Nachdem ich den Fehler bei zeilenweisem Durchschauen des/der Codes nicht finden konnte, habe ich jetzt angefangen, Code-Teile auszukommentieren, solange, bis der launch Fehler nicht mehr auftrat. Dabei habe ich festgestellt, dass es am Ende reicht, die enc und dec Funktionen auszukommentieren. Darin muss also der Fehler liegen. Sind die "weg", kriege ich eine Ausgabe:

snapshot44.png

[Edit]
Ich habe die Fehlerquelle für den launch error gefunden. Das "4*b" in den Aufrufen der Funktionen. Wenn das weg ist, wird zwar falsch ver- und entschlüsselt, aber der Code läuft ganz normal durch:

snapshot45.png

Wenn ich jetzt bloß noch wüsste, was genau an der Berechnug mit den 4*b falsch ist, und wie ich das beheben könnte ... :huh:
 
Zuletzt bearbeitet:
So habe mir grade mal den Code zu Twofish angeguckt und hab schon an meinem eigenen Verstand gezweifelt bis es mir endlich aufgefallen ist. Neben mehreren fehlenden __device__ an den Funktionen und der nicht richtigen Schlüsselinitialisierung war der Fehler für "Unspecified launch failure" im std_defs.h Header zu suchen. Dort wird unsigned long als 4 Byte Typ verkauft, allerdings unter Linux x64 ist unsigned long meistens 8 Byte. Ich hab die Typen einfach mit den entsprechenden Varianten aus stdint.h ersetzt und jetzt scheint es zu funktionieren. Hab dir hier Anhang anzeigen twofish.zip mal den Code hochgeladen.

Edit: Und der AES Code funktioniert jetzt auch. Schlüsselinitialisierung ist fummelig und wieder komisches define für unsigned long. Code hier: Anhang anzeigen aes.cu.zip

Bei MARS lass ich dich erstmal noch ein bisschen probieren. Dort ist auch garantiert das typedef wieder mit unsigned long. Ansonsten hoffe ich, dass du dir meinen Code nicht einfach übernimmst sondern dir auch anguckst was ich verändert habe und verstehst wieso.
 
Zuletzt bearbeitet:
Yo boss3D, bekomms ja nur am Rand mit, aber du schuldest sebi was, weil er dir dauernd hilft. Ich würd ihm ja mal nen billiges Steamspiel kaufen oder nen selbstgebackenes Schokoeis per Post schicken... Wäre zumindest eine Geste des Dankes :D
(ne ich will mich hier nich einmischen, aber ich dachte, es schreibt mal ein anderer als ihr beide in diesen thread :P )
 
Zuletzt bearbeitet:
Twofish läuft bei mir in deiner Version, bei AES habe ich nur folgende beiden Zeilen hinzugefügt ...
Code:
HandleError(cudaFree(key_device));
HandleError(cudaFree(key_w));
... aber AES liefert mir immer noch unspecified launch failure. Wenn's aber bei dir auf der GTX 560 Ti läuft, schiebe ich das auf meine unzureichende 9600M GT.

Zum Verständnis: Einfach nur übernehmen kann ich die Codes alleine schon deswegen nicht, weil ich sie vor Lehrern und "Fachpublikum" erklären können muss. ;)

Deswegen habe ich auch folgende Fragen:
- Wofür genau hast du bei Twofish jetzt Speicher im VRAM für den Schlüssel (key_device) allokiert? Weil du set_key() zu einer __device__ Funktion gemacht hast, das als kernel aufrufst, und die Daten somit im VRAM sein müssen?!
- ^^ War das nötig, und wenn ja, warum? Warum genau läuft's jetzt, und vorher nicht, als der Schlüssel von der CPU berechnet wurde?
- Zu strlen(blabla) zählst du jetzt immer +1 dazu wegen '\0'? Dann muss ich das ja auch in RC6 und Serpent noch ergänzen, oder?
- Bei AES erklärt sich das ganze genau gleich, oder?
- Die Zeitmessung soll wirklich in jedem Algorithmus ausschließlich (!) die Dauer (bzw. bei uns die Performance) des Ver- und Entschlüsselns ermitteln. Dass der Schlüssel jetzt in Twofish und AES auch von der GPU berechnet wird, hat darauf eh keinen Einfluss?! Immerhin hast du den kernel ja außerhalb der cudaEvents aufgerufen. Oder müsste ich den Schlüssel jetzt in allen 5 Codes von der GPU berechnen lassen?

MARS schaue ich mir nochmal an. Wieder mal VIELEN DANK bis hier her!!! :daumen:

[Edit]
MARS habe ich jetzt folgendermaßen:
Code:
/* This is an independent implementation of the encryption algorithm:   */

/*                                                                      */

/*         MARS by a team at IBM,                                        */

/*                                                                      */

/* which is a candidate algorithm in the Advanced Encryption Standard   */

/* programme of the US National Institute of Standards and Technology.  */

/* Copyright in this implementation is held by Dr B R Gladman. The MARS */

/* algorithm is covered by a pending patent application owned by IBM,   */

/* who intend to offer a royalty free license under any issued patent   */

/* that results from such application if MARS is selected as the AES    */

/* algorithm.  In the interim, you may evaluate the MARS algorithm for  */

/* your personal, lawful, non-profit purposes as an end user.           */

/*                                                                      */

/* The header above modified on June 6th 1999.                          */

/* Dr Brian Gladman (gladman@seven77.demon.co.uk) 14th January 1999     */



/* Timing data for MARS (mars.c)



128 bit key:

Key Setup:    4316 cycles

Encrypt:       369 cycles =    69.4 mbits/sec

Decrypt:       376 cycles =    68.1 mbits/sec

Mean:          373 cycles =    68.7 mbits/sec



192 bit key:

Key Setup:    4377 cycles

Encrypt:       373 cycles =    68.6 mbits/sec

Decrypt:       379 cycles =    67.5 mbits/sec

Mean:          376 cycles =    68.1 mbits/sec



256 bit key:

Key Setup:    4340 cycles

Encrypt:       369 cycles =    69.4 mbits/sec

Decrypt:       376 cycles =    68.1 mbits/sec

Mean:          373 cycles =    68.7 mbits/sec



*/



#include "std_defs.h"
#include <stdio.h>



static char *alg_name[] = { "mars", "mars.c", "mars" };



char **cipher_name()

{

    return alg_name;

}



__device__ static u4byte s_box[] =

{

    0x09d0c479, 0x28c8ffe0, 0x84aa6c39, 0x9dad7287, /* 0x000    */

    0x7dff9be3, 0xd4268361, 0xc96da1d4, 0x7974cc93,

    0x85d0582e, 0x2a4b5705, 0x1ca16a62, 0xc3bd279d,

    0x0f1f25e5, 0x5160372f, 0xc695c1fb, 0x4d7ff1e4,

    0xae5f6bf4, 0x0d72ee46, 0xff23de8a, 0xb1cf8e83, /* 0x010    */

    0xf14902e2, 0x3e981e42, 0x8bf53eb6, 0x7f4bf8ac,

    0x83631f83, 0x25970205, 0x76afe784, 0x3a7931d4,

    0x4f846450, 0x5c64c3f6, 0x210a5f18, 0xc6986a26,

    0x28f4e826, 0x3a60a81c, 0xd340a664, 0x7ea820c4, /* 0x020    */

    0x526687c5, 0x7eddd12b, 0x32a11d1d, 0x9c9ef086,

    0x80f6e831, 0xab6f04ad, 0x56fb9b53, 0x8b2e095c,

    0xb68556ae, 0xd2250b0d, 0x294a7721, 0xe21fb253,

    0xae136749, 0xe82aae86, 0x93365104, 0x99404a66, /* 0x030    */

    0x78a784dc, 0xb69ba84b, 0x04046793, 0x23db5c1e,

    0x46cae1d6, 0x2fe28134, 0x5a223942, 0x1863cd5b,

    0xc190c6e3, 0x07dfb846, 0x6eb88816, 0x2d0dcc4a,

    0xa4ccae59, 0x3798670d, 0xcbfa9493, 0x4f481d45, /* 0x040    */

    0xeafc8ca8, 0xdb1129d6, 0xb0449e20, 0x0f5407fb,

    0x6167d9a8, 0xd1f45763, 0x4daa96c3, 0x3bec5958,

    0xababa014, 0xb6ccd201, 0x38d6279f, 0x02682215,

    0x8f376cd5, 0x092c237e, 0xbfc56593, 0x32889d2c, /* 0x050    */

    0x854b3e95, 0x05bb9b43, 0x7dcd5dcd, 0xa02e926c,

    0xfae527e5, 0x36a1c330, 0x3412e1ae, 0xf257f462,

    0x3c4f1d71, 0x30a2e809, 0x68e5f551, 0x9c61ba44,

    0x5ded0ab8, 0x75ce09c8, 0x9654f93e, 0x698c0cca, /* 0x060    */

    0x243cb3e4, 0x2b062b97, 0x0f3b8d9e, 0x00e050df,

    0xfc5d6166, 0xe35f9288, 0xc079550d, 0x0591aee8,

    0x8e531e74, 0x75fe3578, 0x2f6d829a, 0xf60b21ae,

    0x95e8eb8d, 0x6699486b, 0x901d7d9b, 0xfd6d6e31, /* 0x070    */

    0x1090acef, 0xe0670dd8, 0xdab2e692, 0xcd6d4365,

    0xe5393514, 0x3af345f0, 0x6241fc4d, 0x460da3a3,

    0x7bcf3729, 0x8bf1d1e0, 0x14aac070, 0x1587ed55,

    0x3afd7d3e, 0xd2f29e01, 0x29a9d1f6, 0xefb10c53, /* 0x080    */

    0xcf3b870f, 0xb414935c, 0x664465ed, 0x024acac7,

    0x59a744c1, 0x1d2936a7, 0xdc580aa6, 0xcf574ca8,

    0x040a7a10, 0x6cd81807, 0x8a98be4c, 0xaccea063,

    0xc33e92b5, 0xd1e0e03d, 0xb322517e, 0x2092bd13, /* 0x090    */

    0x386b2c4a, 0x52e8dd58, 0x58656dfb, 0x50820371,

    0x41811896, 0xe337ef7e, 0xd39fb119, 0xc97f0df6,

    0x68fea01b, 0xa150a6e5, 0x55258962, 0xeb6ff41b,

    0xd7c9cd7a, 0xa619cd9e, 0xbcf09576, 0x2672c073, /* 0x0a0    */

    0xf003fb3c, 0x4ab7a50b, 0x1484126a, 0x487ba9b1,

    0xa64fc9c6, 0xf6957d49, 0x38b06a75, 0xdd805fcd,

    0x63d094cf, 0xf51c999e, 0x1aa4d343, 0xb8495294,

    0xce9f8e99, 0xbffcd770, 0xc7c275cc, 0x378453a7, /* 0x0b0    */

    0x7b21be33, 0x397f41bd, 0x4e94d131, 0x92cc1f98,

    0x5915ea51, 0x99f861b7, 0xc9980a88, 0x1d74fd5f,

    0xb0a495f8, 0x614deed0, 0xb5778eea, 0x5941792d,

    0xfa90c1f8, 0x33f824b4, 0xc4965372, 0x3ff6d550, /* 0x0c0    */

    0x4ca5fec0, 0x8630e964, 0x5b3fbbd6, 0x7da26a48,

    0xb203231a, 0x04297514, 0x2d639306, 0x2eb13149,

    0x16a45272, 0x532459a0, 0x8e5f4872, 0xf966c7d9,

    0x07128dc0, 0x0d44db62, 0xafc8d52d, 0x06316131, /* 0x0d0    */

    0xd838e7ce, 0x1bc41d00, 0x3a2e8c0f, 0xea83837e,

    0xb984737d, 0x13ba4891, 0xc4f8b949, 0xa6d6acb3,

    0xa215cdce, 0x8359838b, 0x6bd1aa31, 0xf579dd52,

    0x21b93f93, 0xf5176781, 0x187dfdde, 0xe94aeb76, /* 0x0e0    */

    0x2b38fd54, 0x431de1da, 0xab394825, 0x9ad3048f,

    0xdfea32aa, 0x659473e3, 0x623f7863, 0xf3346c59,

    0xab3ab685, 0x3346a90b, 0x6b56443e, 0xc6de01f8,

    0x8d421fc0, 0x9b0ed10c, 0x88f1a1e9, 0x54c1f029, /* 0x0f0    */

    0x7dead57b, 0x8d7ba426, 0x4cf5178a, 0x551a7cca,

    0x1a9a5f08, 0xfcd651b9, 0x25605182, 0xe11fc6c3,

    0xb6fd9676, 0x337b3027, 0xb7c8eb14, 0x9e5fd030,



    0x6b57e354, 0xad913cf7, 0x7e16688d, 0x58872a69, /* 0x100    */

    0x2c2fc7df, 0xe389ccc6, 0x30738df1, 0x0824a734,

    0xe1797a8b, 0xa4a8d57b, 0x5b5d193b, 0xc8a8309b,

    0x73f9a978, 0x73398d32, 0x0f59573e, 0xe9df2b03,

    0xe8a5b6c8, 0x848d0704, 0x98df93c2, 0x720a1dc3, /* 0x110    */

    0x684f259a, 0x943ba848, 0xa6370152, 0x863b5ea3,

    0xd17b978b, 0x6d9b58ef, 0x0a700dd4, 0xa73d36bf,

    0x8e6a0829, 0x8695bc14, 0xe35b3447, 0x933ac568,

    0x8894b022, 0x2f511c27, 0xddfbcc3c, 0x006662b6, /* 0x120    */

    0x117c83fe, 0x4e12b414, 0xc2bca766, 0x3a2fec10,

    0xf4562420, 0x55792e2a, 0x46f5d857, 0xceda25ce,

    0xc3601d3b, 0x6c00ab46, 0xefac9c28, 0xb3c35047,

    0x611dfee3, 0x257c3207, 0xfdd58482, 0x3b14d84f, /* 0x130    */

    0x23becb64, 0xa075f3a3, 0x088f8ead, 0x07adf158,

    0x7796943c, 0xfacabf3d, 0xc09730cd, 0xf7679969,

    0xda44e9ed, 0x2c854c12, 0x35935fa3, 0x2f057d9f,

    0x690624f8, 0x1cb0bafd, 0x7b0dbdc6, 0x810f23bb, /* 0x140    */

    0xfa929a1a, 0x6d969a17, 0x6742979b, 0x74ac7d05,

    0x010e65c4, 0x86a3d963, 0xf907b5a0, 0xd0042bd3,

    0x158d7d03, 0x287a8255, 0xbba8366f, 0x096edc33,

    0x21916a7b, 0x77b56b86, 0x951622f9, 0xa6c5e650, /* 0x150    */

    0x8cea17d1, 0xcd8c62bc, 0xa3d63433, 0x358a68fd,

    0x0f9b9d3c, 0xd6aa295b, 0xfe33384a, 0xc000738e,

    0xcd67eb2f, 0xe2eb6dc2, 0x97338b02, 0x06c9f246,

    0x419cf1ad, 0x2b83c045, 0x3723f18a, 0xcb5b3089, /* 0x160    */

    0x160bead7, 0x5d494656, 0x35f8a74b, 0x1e4e6c9e,

    0x000399bd, 0x67466880, 0xb4174831, 0xacf423b2,

    0xca815ab3, 0x5a6395e7, 0x302a67c5, 0x8bdb446b,

    0x108f8fa4, 0x10223eda, 0x92b8b48b, 0x7f38d0ee, /* 0x170    */

    0xab2701d4, 0x0262d415, 0xaf224a30, 0xb3d88aba,

    0xf8b2c3af, 0xdaf7ef70, 0xcc97d3b7, 0xe9614b6c,

    0x2baebff4, 0x70f687cf, 0x386c9156, 0xce092ee5,

    0x01e87da6, 0x6ce91e6a, 0xbb7bcc84, 0xc7922c20, /* 0x180    */

    0x9d3b71fd, 0x060e41c6, 0xd7590f15, 0x4e03bb47,

    0x183c198e, 0x63eeb240, 0x2ddbf49a, 0x6d5cba54,

    0x923750af, 0xf9e14236, 0x7838162b, 0x59726c72,

    0x81b66760, 0xbb2926c1, 0x48a0ce0d, 0xa6c0496d, /* 0x190    */

    0xad43507b, 0x718d496a, 0x9df057af, 0x44b1bde6,

    0x054356dc, 0xde7ced35, 0xd51a138b, 0x62088cc9,

    0x35830311, 0xc96efca2, 0x686f86ec, 0x8e77cb68,

    0x63e1d6b8, 0xc80f9778, 0x79c491fd, 0x1b4c67f2, /* 0x1a0    */

    0x72698d7d, 0x5e368c31, 0xf7d95e2e, 0xa1d3493f,

    0xdcd9433e, 0x896f1552, 0x4bc4ca7a, 0xa6d1baf4,

    0xa5a96dcc, 0x0bef8b46, 0xa169fda7, 0x74df40b7,

    0x4e208804, 0x9a756607, 0x038e87c8, 0x20211e44, /* 0x1b0    */

    0x8b7ad4bf, 0xc6403f35, 0x1848e36d, 0x80bdb038,

    0x1e62891c, 0x643d2107, 0xbf04d6f8, 0x21092c8c,

    0xf644f389, 0x0778404e, 0x7b78adb8, 0xa2c52d53,

    0x42157abe, 0xa2253e2e, 0x7bf3f4ae, 0x80f594f9, /* 0x1c0    */

    0x953194e7, 0x77eb92ed, 0xb3816930, 0xda8d9336,

    0xbf447469, 0xf26d9483, 0xee6faed5, 0x71371235,

    0xde425f73, 0xb4e59f43, 0x7dbe2d4e, 0x2d37b185,

    0x49dc9a63, 0x98c39d98, 0x1301c9a2, 0x389b1bbf, /* 0x1d0    */

    0x0c18588d, 0xa421c1ba, 0x7aa3865c, 0x71e08558,

    0x3c5cfcaa, 0x7d239ca4, 0x0297d9dd, 0xd7dc2830,

    0x4b37802b, 0x7428ab54, 0xaeee0347, 0x4b3fbb85,

    0x692f2f08, 0x134e578e, 0x36d9e0bf, 0xae8b5fcf, /* 0x1e0    */

    0xedb93ecf, 0x2b27248e, 0x170eb1ef, 0x7dc57fd6,

    0x1e760f16, 0xb1136601, 0x864e1b9b, 0xd7ea7319,

    0x3ab871bd, 0xcfa4d76f, 0xe31bd782, 0x0dbeb469,

    0xabb96061, 0x5370f85d, 0xffb07e37, 0xda30d0fb, /* 0x1f0    */

    0xebc977b6, 0x0b98b40f, 0x3a4d0fe6, 0xdf4fc26b,

    0x159cf22a, 0xc298d6e2, 0x2b78ef6a, 0x61a94ac0,

    0xab561187, 0x14eea0f0, 0xdf0d4164, 0x19af70ee

};



__device__ static u4byte vk[47] =

{

    0x09d0c479, 0x28c8ffe0, 0x84aa6c39, 0x9dad7287, 0x7dff9be3, 0xd4268361,

    0xc96da1d4

};



__device__ static u4byte   l_key[40];

#define HandleError(x) HandleErrorImpl(x, __FILE__, __LINE__)

#define f_mix(a,b,c,d)                  \
        r = rotr(a, 8);                 \
        b ^= s_box[a & 255];            \
        b += s_box[(r & 255) + 256];    \
        r = rotr(a, 16);                \
        a  = rotr(a, 24);               \
        c += s_box[r & 255];            \
        d ^= s_box[(a & 255) + 256];



#define b_mix(a,b,c,d)                  \
        r = rotl(a, 8);                 \
        b ^= s_box[(a & 255) + 256];    \
        c -= s_box[r & 255];            \
        r = rotl(a, 16);                \
        a  = rotl(a, 24);               \
        d -= s_box[(r & 255) + 256];    \
        d ^= s_box[a & 255];



#define f_ktr(a,b,c,d,i)    \
    m = a + l_key[i];       \
    a = rotl(a, 13);        \
    r = a * l_key[i + 1];   \
    l = s_box[m & 511];     \
    r = rotl(r, 5);         \
    c += rotl(m, r);        \
    l ^= r;                 \
    r = rotl(r, 5);         \
    l ^= r;                 \
    d ^= r;                 \
    b += rotl(l, r);



#define r_ktr(a,b,c,d,i)    \
    r = a * l_key[i + 1];   \
    a = rotr(a, 13);        \
    m = a + l_key[i];       \
    l = s_box[m & 511];     \
    r = rotl(r, 5);         \
    l ^= r;                 \
    c -= rotl(m, r);        \
    r = rotl(r, 5);         \
    l ^= r;                 \
    d ^= r;                 \
    b -= rotl(l, r);



/* For a 32 bit word (x) generate a mask (m) such that a bit in */

/* m is set to 1 if and only if the corresponding bit in x is:  */

/*                                                              */

/* 1. in a sequence of 10 or more adjacent '0' bits             */

/* 2. in a sequence of 10 or more adjacent '1' bits             */

/* 3. but is not either endpoint of such a sequence unless such */

/*    an endpoint is at the top bit (bit 31) of a word and is   */

/*    in a sequence of '0' bits.                                */

/*                                                              */

/* The only situation in which a sequence endpoint is included  */

/* in the mask is hence when the endpoint is at bit 31 and is   */

/* the endpoint of a sequence of '0' bits. My thanks go to Shai */

/* Halevi of IBM for the neat trick (which I missed) of finding */

/* the '0' and '1' sequences at the same time.                  */



__device__ u4byte gen_mask(u4byte x)

{   u4byte  m;



    /* if m{bn} stands for bit number bn of m, set m{bn} = 1 if */

    /* x{bn} == x{bn+1} for 0 <= bn <= 30.  That is, set a bit  */

    /* in m if the corresponding bit and the next higher bit in */

    /* x are equal in value (set m{31} = 0).                    */



    m = (~x ^ (x >> 1)) & 0x7fffffff;



    /* Sequences of 9 '1' bits in m now correspond to sequences */

    /* of 10 '0's or 10 '1' bits in x.  Shift and 'and' bits in */

    /* m to find sequences of 9 or more '1' bits.   As a result */

    /* bits in m are set if they are at the bottom of sequences */

    /* of 10 adjacent '0's or 10 adjacent '1's in x.            */



    m &= (m >> 1) & (m >> 2); m &= (m >> 3) & (m >> 6);



    if(!m)  /* return if mask is empty - no key fixing needed   */

            /* is this early return worthwhile?                 */

        return 0;



    /* We need the internal bits in each continuous sequence of */

    /* matching bits (that is the bits less the two endpoints). */

    /* We thus propagate each set bit into the 8 internal bits  */

    /* that it represents, starting 1 left and finsihing 8 left */

    /* of its position.                                         */



    m <<= 1; m |= (m << 1); m |= (m << 2); m |= (m << 4);



    /* m is now correct except for the odd behaviour of bit 31, */

    /* that is, it will be set if it is in a sequence of 10 or  */

    /* more '0's and clear otherwise.                           */



    m |= (m << 1) & ~x & 0x80000000;



    return m & 0xfffffffc;

};



/* My thanks to Louis Granboulan for spotting an error in the   */

/* previous version of set_key.                                 */



__global__ void set_key(const u4byte in_key[], const u4byte key_len)

{   u4byte  i, j, m, w;



    m = key_len / 32 - 1;



    for(i = j = 0; i < 39; ++i)

    {

      vk[i + 7] = rotl(vk[i] ^ vk[i + 5], 3) ^ in_key[j] ^ i;



      j = (j == m ? 0 : j + 1);

    }



    vk[46] = key_len / 32;



    for(j = 0; j < 7; ++j)

    {

         for(i = 1; i < 40; ++i)



            vk[i + 7] = rotl(vk[i + 7] + s_box[vk[i + 6] & 511], 9);



        vk[7] = rotl(vk[7] + s_box[vk[46] & 511], 9);

    }



    for(i = j = 0; i < 40; ++i)

    {

        l_key[j] = vk[i + 7];



        j = (j < 33 ? j + 7 : j - 33);

    }



    for(i = 5; i < 37; i += 2)

    {

        w = l_key[i] | 3;



        if(m = gen_mask(w))



            w ^= (rotl(s_box[265 + (l_key[i] & 3)], l_key[i + 3] & 31) & m);



        l_key[i] = w;

    }


};



__device__ void encrypt(const u4byte in_blk[4], u4byte out_blk[4])

{   u4byte  a, b, c, d, l, m, r;



    a = in_blk[0] + l_key[0]; b = in_blk[1] + l_key[1];

    c = in_blk[2] + l_key[2]; d = in_blk[3] + l_key[3];



    f_mix(a,b,c,d); a += d;

    f_mix(b,c,d,a); b += c;

    f_mix(c,d,a,b);

    f_mix(d,a,b,c);

    f_mix(a,b,c,d); a += d;

    f_mix(b,c,d,a); b += c;

    f_mix(c,d,a,b);

    f_mix(d,a,b,c);



    f_ktr(a,b,c,d, 4); f_ktr(b,c,d,a, 6); f_ktr(c,d,a,b, 8); f_ktr(d,a,b,c,10);

    f_ktr(a,b,c,d,12); f_ktr(b,c,d,a,14); f_ktr(c,d,a,b,16); f_ktr(d,a,b,c,18);

    f_ktr(a,d,c,b,20); f_ktr(b,a,d,c,22); f_ktr(c,b,a,d,24); f_ktr(d,c,b,a,26);

    f_ktr(a,d,c,b,28); f_ktr(b,a,d,c,30); f_ktr(c,b,a,d,32); f_ktr(d,c,b,a,34);



    b_mix(a,b,c,d);

    b_mix(b,c,d,a); c -= b;

    b_mix(c,d,a,b); d -= a;

    b_mix(d,a,b,c);

    b_mix(a,b,c,d);

    b_mix(b,c,d,a); c -= b;

    b_mix(c,d,a,b); d -= a;

    b_mix(d,a,b,c);



    out_blk[0] = a - l_key[36]; out_blk[1] = b - l_key[37];

    out_blk[2] = c - l_key[38]; out_blk[3] = d - l_key[39];

};



__device__ void decrypt(const u4byte in_blk[4], u4byte out_blk[4])

{   u4byte  a, b, c, d, l, m, r;



    d = in_blk[0] + l_key[36]; c = in_blk[1] + l_key[37];

    b = in_blk[2] + l_key[38]; a = in_blk[3] + l_key[39];



    f_mix(a,b,c,d); a += d;

    f_mix(b,c,d,a); b += c;

    f_mix(c,d,a,b);

    f_mix(d,a,b,c);

    f_mix(a,b,c,d); a += d;

    f_mix(b,c,d,a); b += c;

    f_mix(c,d,a,b);

    f_mix(d,a,b,c);



    r_ktr(a,b,c,d,34); r_ktr(b,c,d,a,32); r_ktr(c,d,a,b,30); r_ktr(d,a,b,c,28);

    r_ktr(a,b,c,d,26); r_ktr(b,c,d,a,24); r_ktr(c,d,a,b,22); r_ktr(d,a,b,c,20);

    r_ktr(a,d,c,b,18); r_ktr(b,a,d,c,16); r_ktr(c,b,a,d,14); r_ktr(d,c,b,a,12);

    r_ktr(a,d,c,b,10); r_ktr(b,a,d,c, 8); r_ktr(c,b,a,d, 6); r_ktr(d,c,b,a, 4);



    b_mix(a,b,c,d);

    b_mix(b,c,d,a); c -= b;

    b_mix(c,d,a,b); d -= a;

    b_mix(d,a,b,c);

    b_mix(a,b,c,d);

    b_mix(b,c,d,a); c -= b;

    b_mix(c,d,a,b); d -= a;

    b_mix(d,a,b,c);



    out_blk[0] = d - l_key[0]; out_blk[1] = c - l_key[1];

    out_blk[2] = b - l_key[2]; out_blk[3] = a - l_key[3];

}

__global__ void mars_enc(const u4byte in_blk[4], u4byte out_blk[4]) {
    int b = blockIdx.x*blockDim.x + threadIdx.x;
    encrypt(in_blk + 4*b, out_blk + 4*b);
}

__global__ void mars_dec(const u4byte in_blk[4], u4byte out_blk[4]) {
    int b = blockIdx.x*blockDim.x + threadIdx.x;
    decrypt(in_blk + 4*b, out_blk + 4*b);
}

inline void HandleErrorImpl(cudaError error, const char* file, int line) {
    if (error != cudaSuccess) {
        printf("%s: %d %s", file, line, cudaGetErrorString(error));
        exit(1);
    }
}

int main(void) {
    int threads = 256;
    int blocks = 25600;

    char* key = "meingeheimespasswort";
    char* key_device;
    HandleError(cudaMalloc(&key_device, strlen(key)+1));
    HandleError(cudaMemcpy(key_device, key, strlen(key)+1, cudaMemcpyHostToDevice));
    set_key<<<1,1>>>((const u4byte*)key, strlen(key));
    HandleError(cudaGetLastError());

    u4byte* in_blk;
    HandleError(cudaMalloc(&in_blk, 16*threads*blocks));
    HandleError(cudaMemset(in_blk, 0, 16*threads*blocks));

    u4byte* out_blk;
    HandleError(cudaMalloc(&out_blk, 16*threads*blocks));

    char *test1 = (char*)malloc(16*threads*blocks);
    HandleError(cudaMemcpy(test1, in_blk, 16*threads*blocks, cudaMemcpyDeviceToHost));

    printf("First 16 bytes of input data: ");
    for (int i=0; i<16; i++) {
        printf("%d, ", test1[i]);
    }

    cudaEvent_t start, stop;
    HandleError(cudaEventCreate(&start));
    HandleError(cudaEventCreate(&stop));
    HandleError(cudaEventRecord( start, 0 ));

    mars_enc<<<blocks,threads>>>(in_blk, out_blk);
    mars_dec<<<blocks,threads>>>(out_blk, in_blk);

    HandleError(cudaGetLastError());

    HandleError(cudaEventRecord( stop, 0 ));
    HandleError(cudaEventSynchronize( stop ));
    float elapsedTime;
    HandleError(cudaEventElapsedTime( &elapsedTime, start, stop ));

    printf("\nPerformance: %.6f MB/sec\n", 2*((16*threads*blocks)/1048576)/(elapsedTime/1000));

    HandleError(cudaEventDestroy( start ));
    HandleError(cudaEventDestroy( stop ));

    char *test2 = (char*)malloc(16*threads*blocks);
    HandleError(cudaMemcpy(test2, in_blk, 16*threads*blocks, cudaMemcpyDeviceToHost));

    printf("After decryption: ");
    for (int i=0; i<16; i++) {
        printf("%d, ", test2[i]);
    }

    free(test1);
    free(test2);

    HandleError(cudaFree(in_blk));
    HandleError(cudaFree(out_blk));
    HandleError(cudaFree(key_device));

    return 0;
}
^^ im Code selbst werden jetzt auch keine Fehler mehr angezeigt, allerdings komme ich beim Ausführen wieder auf den altbekannten unspecified launch failure. Angeblich soll er von Zeile 795 verursacht werden:
Code:
HandleError(cudaMemcpy(test1, in_blk, 16*threads*blocks, cudaMemcpyDeviceToHost));
Twofish und AES liefern jetzt bei weiteren Durchläufen auch nur noch diesen unspecified launch failure. Aber ich vertraue jetzt ganz darauf, dass die Codes bei dir auf der GTX 560 Ti wirklich einwandfrei laufen und ich den Fehler nur wegen meiner zu schwachen 9600M GT kriege ...

Was sollte es denn sonst sein, wenn wir idente Twofish und AES haben?
 
Zuletzt bearbeitet:
Also die Twofish Implementierung unterscheiden sich von denen davor dadurch, dass Schlüssel und alles in globalen Variablen liegen. Statt also ein struct das den Schlüssel enthält in den VRAM zu kopieren macht es eher Sinn alle Funktionen als __device__ Funktionen zu deklarieren und die Daten für den Schlüssel einfach auch von der GPU erstellen zu lassen. Da Strings in C aber auch nur Pointer auf char sind muss man das ganze wieder in den VRAM kopieren vorm Aufruf. Das war jedenfalls der Teil für die erfolgreiche Schlüsselinitialisierung.

Der Zeit der mich vorhin viel mehr Zeit gekostet hat war, wegen dem falschen typedef. Ich hatte ja schon geschrieben, dass aufgrund eines Fehlers im Header der Typ u4byte tatsächlich 8 Byte groß war. Das führt dann zu massiv Problemen bei sowas wie "in_blk + 4*b" Wo wir eigentlich 16 Byte weiter wollten um mit jedem b einen neuen Block zu erwischen. Denn statt 4*4Byte vorwärts zu gehen werden jetzt 4*8Byte übersprungen. Daher kam also der "Unspecified launch failure" weil wir Speicher gelesen und geschrieben haben der weit außerhalb des reservierten Bereichs lieg.

Ja ich mache dort strlen()+1 weil ich das abschließende '\0' mitkopieren möchte. Wenn du genau guckst dann mache ich das aber nur beim reservieren des Speichers und kopieren der Daten aber nicht beim übergeben an die Funktion set_key. Du brauchst das also bei RC6 und Serpent nicht zu machen.

Ob die Schlüssel jetzt von der CPU berechnet werden und anschließend auf die GPU kopiert werden oder direkt auf der GPU generiert werden hat auf die spätere Geschwindigkeit des Algorithmus keinen Einfluss. Muss man eben nur sehen, dass Start und Stop-Event nur die Ver- und Entschlüsselung enthält.

Das du immer noch einen "Unspecified launch failure" bei Twofish und AES erhälst wundert mich. Eigentlich sollte das so auch auf deiner Hardware laufen. Wenn du weiterhin unspecified launch failure kriegst empfehle ich dir nochmals cuda-memcheck. Das Tool ist sehr leicht zu bedienen (verglichen mit gdb oder cuda-gdb). Du musst nur "cuda-memcheck *progname*" in der Console eintippen und schon sollte dir das Programm alle Speicherfehler reportieren.

Abschließend noch ein Fehler der mir vorhin aufgefallen ist. Twofish und MARS die set_key Funktion erwartet als Länge nicht die des Schlüssels in Bytes sondern Bits. Also beim Übergeben noch ein *8 ergänzen. Bei MARS führt ein falscher Wert dort auch zu Speicherfehlern.
 
Okay, strlen(key)*8 habe ich jetzt in Twofish und MARS auch noch drinnen. Bei mir sieht's jetzt nach den letzten Fehlerkorrekturen so aus:

AES: the launch timed out and was terminated (Zeile 816)
MARS: unspecified launch failure (Zeile 795)
RC6: the launch timed out and was terminated (Zeile 178)
Serpent: funktioniert (22 MB/s)
Twofish: funktioniert (18 MB/s)

^^ Ich schaue mir das jetzt mal mit cuda-memcheck an ...

[Edit]
Jetzt muss ich nur noch rausfinden, was das alles bedeutet:

snapshot49.png snapshot50.png snapshot51.png

[Edit2]
Fehler in MARS ist behoben; war nur ein blöder "Schlampigkeitsfehler". Ich hatte in set_key() nur "key" statt "key_device" angegeben. Der Test fällt jedenfalls beeindruckend aus! MARS ist von meinen 3 funktionierenden bis jetzt der mit Abstand performanteste Algorithmus:

snapshot52.png

Beiben noch AES und RC6 ...

[Edit3]
RC6 funktioniert, wenn ich wenige Threads (256) und Blöcke (12800) einstelle. Also liegt das Problem wohl wirklich nur an meiner zu schwachen 9600M GT. Die schwache Performance sagt jetzt im Vergleich mit den anderen, deutlich besser parallelisierten Algorithmen natürlich nichts aus. Das wird dann erst auf dem GTX 560 Ti SLI mit selber Thread-/Blockanzahl interessant:

snapshot53.png

Bleibt nur noch AES ...

[Edit4]

AES hatte das ganz gleiche Problem wie RC6. Die GPU packte es einfach nicht. Jetzt mit 128 Threads / 6400 Blöcken funktioniert AES. Das wird wohl auch erst am Benchmarksystem interessant:

snapshot54.png

^^ Damit funktionieren jetzt endlich auch alle Codes bei mir! ;)
----------------

Übrigens weiß ich jetzt auch, wie das mit den Rundenschlüsseln gemeint war.:

Beginnend beim Schlüssel 0x00000000..00 einfach die Schlüssel 0x00000000..01, 0x00000000..02 usw. probieren. Mit key++ weiterspringen.

Aber ich denke, das lassen wir vorerst. Wenn wir jetzt alle Codes auf das umschreiben, bringen wir wahrscheinlich nur wieder Fehler rein, die wir dann wieder in stundenlanger Arbeit suchen müssten. Oder wüsstest du sofort und mit Sicherheit, wie das ginge?
 
Zuletzt bearbeitet:
Mir ist immer noch nicht ganz klar welcher Schlüssel gemeint ist. Die Passphrase oder das was die einzelnen Algos daraus generieren? In jedem Fall wäre das überhaupt nicht einfach zu implementieren. Zumindest nicht schön parallel, da man nach jedem Block nochmal neu set_key oder ähnliches aufrufen müsste, was die ganze Sache extremst verlangsamen würde.

Noch eine Sache die mir aufgefallen ist. AES und einige andere verschlüsselungen gibt es als verschiedene Varianten mit unterschliedlich großen Keys. Bei AES z.b. gibts 128, 192 und 256 Bit als Keysize. Die Varianten kann man einfach durch setzten der keysize Variablen in der main() Funktion ändern. Momentan ist die 256 Bit Variante eingestellt die wohl auch die langsamste Variante ist. Ich würde also AES in allen 3 Versionen benchmarken. Einige andere Verschlüsselungen haben das vermutlich auch. Musste mal bei Wikipedia gucken bei welchen das der Fall ist und wie man das umschalten kann (falls das bei der Implementierung überhaupt umzuschalten geht).
 
So, wie ich das jetzt verstehe, sollte 0x00000000...0 unsere Passphrase ersetzen, und die Schlüsselberechnungsfunktionen sollten dann nichts anderes machen als key++. Aber wenn wir die Codes jetzt darauf umbasteln kommen sicher wieder 100 Errors. Das will ich mir nicht mehr antun. Außerdem müsste das ganze bis morgen 10:30 fertig sein. Das wäre eh schon zu knapp.

Ja, das mit den Schlüsseln kann ich dann beim Benchmarken durchaus berücksichtigen. Wenn's möglich ist, alle Algorithmen mit allen möglichen (aber immer der jeweils gleichen) Schlüssel-Längen zu benchmarken ...

[Edit]
Außerdem denke ich mir auch, dass das mit 0x00000000...0, 0x00000000...1, 0x00000000...2, etc. doch auch total einfach zu bruteforcen sein muss?! Jedenfalls ist das sicher leichter zu erraten als eine x-beliebige Passphrase?!
 
Hab grade mal geguckt. Alle 5 Verschlüsselungen unterstützen tatsächlich die gleichen Schlüsselllängen von 128, 192 und 256 Bit. Ich glaube aber eher nicht, dass man bei allen Implementation das umstellen kann. Ich würde daher bei denen wo man es umstellen kann alle 3 Varianten in der Benchmark Liste als z.B. AES-128, AES-192 und AES-256 aufnehmen und da wo man es nicht umstellen kann rausfinden welche der 3 Varianten benutzt wird und dann die Bitzahl auch dahinter schreiben.
 
Außer bei AES kann man es eh bei keinem unserer anderen 4 Algorithmen einfach so umstellen. Und ich traue mich nicht so recht, da jetzt herumbasteln zu probieren, bevor am Ende wieder alle Codes nur failures und errors liefern.

Mich verwirrt das auch, was du da bei AES reingebaut hast. Dieses key_device. Wozu brauchen wir denn überhaupt noch unsere key Passphrase, wenn wir eh key_device in der Größe des Schlüssel (128, 192, oder 256) haben?
 
Mir ist grade noch ein kleiner Fehler in AES aufgefallen. Eigentlich sollte key_device nur keysize/8 groß sein, da keysize in Bits ist. Also bei dem cudaMalloc und cudaMemset sollte keysize/8 stehen.

Die KeyExpansion Funktion von AES erwartet, dass key_device mindstens so viele Bits groß ist wie man in keysize angibt. Daher setze ich zuerst alles auf 0 und kopiere dann unseren Passphrase drüber. Aus dem 256 Bit key_device werden dann die Rundenschlüssel abgeleitet und in key_w gespeichert.
 
Hey,
find ich ein interessantes Projekt.
Du machst das alles mit Eclipse cdt ?
Kanst du vll. kurz sagen wie viel schneller Aes in Cuda läuft ? Ich hab mir jetzt nicht den mompletten Thread durchgelesen ;)
 
Hi!

Ich arbeite mit der von nVidia zum Download angebotenen Nsight Edition von Eclipse unter Kubuntu 13.10. Ich hatte das Projekt unter Windows 7 mit Visual Studio 2010 Nsight begonnen, war dann aber "so schlau", auf Visual Studio 2013 upzugraden ohne mich vorher darüber zu informieren, dass das noch nicht von CUDA 5.5 unterstützt wird. Da ich aber nicht wieder stundenlange downgraden wollte, blieb mir eben nur Linux/Eclipse (war am Ende aber kein Problem) ...

AES-256 ist auf GPU dank Parallelisierung in folgendem Ausmaß performanter, als ohne:
9600M GT, 1 Thread / 1 Block: 0.000000 MB/sec
9600M GT, 128 Threads / 200 Blocks: 0.000000 MB/sec
9600M GT, 128 Threads / 800 Blocks: 1.513634 MB/sec
9600M GT, 128 Threads / 6400 Blocks: 2.256983 MB/sec
("vernünftige" Werte auf potenter Hardware folgen noch)
^^ Die ersten beiden Ergebnisse haben mich selbst überrascht, aber scheinbar "muss" AES parallelisiert sein, um auf dieser extremst schwachen GPU überhaupt vernünftige Datenmengen verarbeiten zu können?! Wobei die Blockanzahl interessanter zu sein scheint, als die Threadanzahl.

Im Moment bin ich damit beschäftigt, die Präsentation des Projekts für die Messe auf der FH vorzubereiten, falls sich wer wundert, warum ich hier (vorerst) nichts mehr zu den Codes schreibe. ;)
 
Cool, ich hab gerade ein Projekt über Wegfindung am Laufen, werde es nach der Präsentation in einem Thread hier veröffentlichen. Hab auch schon über Parallelisierung nachgedacht, da das mit Java Aparapi ziemlich komfortabel funktionieren soll.
Das Problem ist nur dass meine Tiefensuche nur aus Rekursion besteht ;( ,
mal schauen ob ich die Breitensuche parallel bekomme.
Jetzt hab ich aber erstmal die Arbeit drüber zu schreiben, 9 Seiten Text sind schon fertig :) .

Ich mache das auch alles unter Kubuntu 13.10 mit Eclipse, läuft echt prima auf meinem Netbook.
 
Zurück