Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cryptographic libraries #144

Draft
wants to merge 10 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
331 changes: 331 additions & 0 deletions src/Home/Crypto/AES128/AES128.ZC
Original file line number Diff line number Diff line change
@@ -0,0 +1,331 @@
#define Nb 4 // The number of columns comprising a state in AES. This is a constant in AES. Value=4
#define Nk 4 // The number of 32 bit words in a key.
#define Nr 10 // amount of rounds to expand the key

// could be calculated on the fly too... i guess
// https://en.wikipedia.org/wiki/Rijndael_S-box
U8 sBox[256] = {
//0 1 2 3 4 5 6 7 8 9 A B C D E F
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
};

// U8 reverse_sBox[256] = {
// 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
// };

U8 Rcon[255] = {
0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a,
0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39,
0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a,
0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8,
0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef,
0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc,
0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b,
0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3,
0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94,
0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20,
0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35,
0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f,
0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04,
0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63,
0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd,
0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb
};

// Mul2 and Mul3 could be precomputed, but here's a simple implementation
// Note: This is a simplified and not optimized version
U8 xtime(U8 x) {
return (x << 1) ^ (((x >> 7) & 1) * 0x1b);
}

U8 Mul2[256], Mul3[256];

U0 InitMulTables() {
I64 i;
for (i = 0; i < 256; i++) {
Mul2[i] = xtime(i);
Mul3[i] = xtime(i) ^ i;
}
}

U0 KeyExpansion(U8 *RoundKey, U8 *Key) {
I64 i, j, k;
U8 tempa[4]; // Temporary storage array

// Copy the original key to the first round key
for (i = 0; i < Nk; ++i) {
RoundKey[(i * 4) + 0] = Key[(i * 4) + 0];
RoundKey[(i * 4) + 1] = Key[(i * 4) + 1];
RoundKey[(i * 4) + 2] = Key[(i * 4) + 2];
RoundKey[(i * 4) + 3] = Key[(i * 4) + 3];
}

// Expand the keys for the remaining rounds
for (i = Nk; i < Nb * (Nr + 1); ++i) {
// Fetch the previous word
k = (i - 1) * 4;
tempa[0] = RoundKey[k + 0];
tempa[1] = RoundKey[k + 1];
tempa[2] = RoundKey[k + 2];
tempa[3] = RoundKey[k + 3];

if (i % Nk == 0) {
// Rotate the word and apply S-box substitution
U8 u8tmp = tempa[0];
tempa[0] = sBox[tempa[1]];
tempa[1] = sBox[tempa[2]];
tempa[2] = sBox[tempa[3]];
tempa[3] = sBox[u8tmp];

// XOR with Rcon[i/Nk]
tempa[0] = tempa[0] ^ Rcon[i / Nk];
}

// XOR tempa with the word Nk positions before
j = i * 4; k = (i - Nk) * 4;
RoundKey[j + 0] = RoundKey[k + 0] ^ tempa[0];
RoundKey[j + 1] = RoundKey[k + 1] ^ tempa[1];
RoundKey[j + 2] = RoundKey[k + 2] ^ tempa[2];
RoundKey[j + 3] = RoundKey[k + 3] ^ tempa[3];
}
}

U0 AddRoundKey(U8 round, U8 *state, U8 *RoundKey) {
I64 i, j;
for (i = 0; i < 4; i++) {
for (j = 0; j < 4; j++) {
state[j * 4 + i] ^= RoundKey[round * Nb * 4 + i * Nb + j];
}
}
}

U0 SubBytes(U8 *state) {
I64 i;
for (i = 0; i < 16; i++) {
state[i] = sBox[state[i]];
}
}

U0 ShiftRows(U8 *state) {
U8 temp;

// Shift the second row (1 shift to the left)
temp = state[1];
state[1] = state[5];
state[5] = state[9];
state[9] = state[13];
state[13] = temp;

// Shift the third row (2 shifts to the left)
temp = state[2];
state[2] = state[10];
state[10] = temp;
temp = state[6];
state[6] = state[14];
state[14] = temp;

// Shift the fourth row (3 shifts to the left)
temp = state[3];
state[3] = state[15];
state[15] = state[11];
state[11] = state[7];
state[7] = temp;
}

U0 MixColumns(U8 *state) {
for (I64 i = 0; i < 4; ++i) {
U8 a0 = state[i * 4 + 0];
U8 a1 = state[i * 4 + 1];
U8 a2 = state[i * 4 + 2];
U8 a3 = state[i * 4 + 3];

U8 r0 = Mul2[a0] ^ Mul3[a1] ^ a2 ^ a3;
U8 r1 = a0 ^ Mul2[a1] ^ Mul3[a2] ^ a3;
U8 r2 = a0 ^ a1 ^ Mul2[a2] ^ Mul3[a3];
U8 r3 = Mul3[a0] ^ a1 ^ a2 ^ Mul2[a3];

state[i * 4 + 0] = r0;
state[i * 4 + 1] = r1;
state[i * 4 + 2] = r2;
state[i * 4 + 3] = r3;
}
}

// U0 InvSubBytes(U8 *state) {
// // Implement inverse of SubBytes
// }

// U0 InvShiftRows(U8 *state) {
// // Implement inverse of ShiftRows
// }

// U0 InvMixColumns(U8 *state) {
// // Implement inverse of MixColumns
// }

// U0 InvCipher(U8 *state, U8 *RoundKey) {
// I64 round;
// // Start by adding the last round key
// AddRoundKey(Nr, state, RoundKey);

// // Perform the rounds in reverse order
// for (round = Nr - 1; round > 0; round--) {
// InvShiftRows(state);
// InvSubBytes(state);
// AddRoundKey(round, state, RoundKey);
// InvMixColumns(state);
// }

// // Final round (without MixColumns)
// InvShiftRows(state);
// InvSubBytes(state);
// AddRoundKey(0, state, RoundKey);
// }

U0 Cipher(U8 *state, U8 *RoundKey) {
I64 round;
// Add the First round key to the state before starting the rounds
AddRoundKey(0, state, RoundKey);

// There will be Nr rounds
for (round = 1; round < Nr; ++round) {
SubBytes(state);
ShiftRows(state);
MixColumns(state);
AddRoundKey(round, state, RoundKey);
}

// The last round is given below
SubBytes(state);
ShiftRows(state);
AddRoundKey(Nr, state, RoundKey);
}

U0 AES_init_ctx(U8 *ctx, U8 *key) {
KeyExpansion(ctx, key);
}

U0 AES_ECB_encrypt(U8 *ctx, U8 *buf) {
// Buffer size is assumed to be multiple of 16 bytes! (AES block size)
Cipher(buf, ctx);
}

// U0 AES_ECB_decrypt(U8 *ctx, U8 *buf) {
// InvCipher(buf, ctx);
// }

U0 PrintHex(U8 *buf, I64 len) {
I64 i;
for (i = 0; i < len; i++) "%02X ", buf[i];
"\n";
}

U8 HexCharToByte(U8 ch) {
if (ch >= '0' && ch <= '9') return ch - '0';
if (ch >= 'a' && ch <= 'f') return 10 + ch - 'a';
if (ch >= 'A' && ch <= 'F') return 10 + ch - 'A';
return 0; // Non-hex character
}

U0 HexStringToByteArray(U8 *hexString, U8 *byteArray, I64 byteArrayLength) {
I64 i;
for (i = 0; i < byteArrayLength; i++) {
byteArray[i] = HexCharToByte(hexString[2 * i]) << 4 | HexCharToByte(hexString[2 * i + 1]);
}
}

// 9d3492551250741cef1bf7892fabd07b
U8 key[16] = {0x9d, 0x34, 0x92, 0x55, 0x12, 0x50, 0x74, 0x1c, 0xef, 0x1b, 0xf7, 0x89, 0x2f, 0xab, 0xd0, 0x7b};
// 0c40d19e21ac91fad03b1a8e5349f245
U8 buf[16] = {0x0c, 0x40, 0xd1, 0x9e, 0x21, 0xac, 0x91, 0xfa, 0xd0, 0x3b, 0x1a, 0x8e, 0x53, 0x49, 0xf2, 0x45};

U0 Main() {
U8 ctx[176]; // Context (expanded key)

InitMulTables();
AES_init_ctx(ctx, key);
AES_ECB_encrypt(ctx, buf);

// `buf` now contains the ciphertext
"Result:\n$$LTRED$$";
PrintHex(buf, 16);
"\n$$FG$$";
}

Main;


// U0 Main() {

// U8 ctx[176]; // Context (expanded key)

// InitMulTables;

// AES_init_ctx(ctx, key);

// "ctx:\n";
// PrintHex(ctx, 176);
// "\n";

// AES_ECB_encrypt(ctx, buf);
// "buf:\n$$LTGREEN$$";
// PrintHex(buf, 16);
// "\n$$FG$$";
// }
// Main;

// // 9d3492551250741cef1bf7892fabd07b
// U8 key[16] = {0x9d, 0x34, 0x92, 0x55, 0x12, 0x50, 0x74, 0x1c, 0xef, 0x1b, 0xf7, 0x89, 0x2f, 0xab, 0xd0, 0x7b};
// // 0c40d19e21ac91fad03b1a8e5349f245
// U8 buf[16] = {0x0c, 0x40, 0xd1, 0x9e, 0x21, 0xac, 0x91, 0xfa, 0xd0, 0x3b, 0x1a, 0x8e, 0x53, 0x49, 0xf2, 0x45};

// U0 Main(U8 *keyHexString, U8 *plaintextHexString) {

// U8 ctx[176]; // Context (expanded key)

// InitMulTables();

// // Convert hex string to byte array for the key
// HexStringToByteArray(keyHexString, key, 16);

// // Convert hex string to byte array for the plaintext
// HexStringToByteArray(plaintextHexString, buf, 16);

// AES_init_ctx(ctx, key);
// AES_ECB_encrypt(ctx, buf);

// // `buf` now contains the ciphertext
// PrintHex(buf, 16);
// }

// // Main("9d3492551250741cef1bf7892fabd07b", "0c40d19e21ac91fad03b1a8e5349f245");
Loading