mirror of
https://github.com/Zeal-Operating-System/ZealOS.git
synced 2024-12-24 22:50:28 +00:00
ChaCha20 and put everything in folder
This commit is contained in:
parent
2b847de048
commit
50a931073b
4 changed files with 247 additions and 58 deletions
|
@ -1,5 +1,5 @@
|
|||
#define Nb 4
|
||||
#define Nk 4
|
||||
#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
|
||||
|
@ -79,35 +79,44 @@ U0 InitMulTables() {
|
|||
}
|
||||
|
||||
U0 KeyExpansion(U8 *RoundKey, U8 *Key) {
|
||||
I64 i, j;
|
||||
// Copy the original key to the round key
|
||||
for (i = 0; i < Nk; i++) {
|
||||
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 round key
|
||||
for (i = Nk; i < Nb * (Nr + 1); i++) {
|
||||
U8 temp[4];
|
||||
for (j = 0; j < 4; j++) {
|
||||
temp[j] = RoundKey[(i-1) * 4 + j];
|
||||
}
|
||||
// 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) {
|
||||
// Perform the rotation within temp array, substitute with S-box, then XOR with Rcon[i/Nk]
|
||||
I64 k = temp[0]; // should be I64 but kept throwing a warning about 64bit variable somehow???
|
||||
k = k & 0xff; // this is an attempt at forcing U8
|
||||
temp[0] = sBox[temp[1]] ^ Rcon[i/Nk];
|
||||
temp[1] = sBox[temp[2]];
|
||||
temp[2] = sBox[temp[3]];
|
||||
temp[3] = sBox[k];
|
||||
// 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];
|
||||
}
|
||||
|
||||
for (j = 0; j < 4; j++) {
|
||||
RoundKey[i * 4 + j] = RoundKey[(i - Nk) * 4 + j] ^ temp[j];
|
||||
}
|
||||
// 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];
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -128,47 +137,47 @@ U0 SubBytes(U8 *state) {
|
|||
}
|
||||
|
||||
U0 ShiftRows(U8 *state) {
|
||||
I64 i;
|
||||
U8 temp[16];
|
||||
U8 temp;
|
||||
|
||||
// Store state in temp
|
||||
for (i = 0; i < 16; i++) {
|
||||
temp[i] = state[i];
|
||||
}
|
||||
// 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 first row 1 columns to left
|
||||
state[0] = temp[0];
|
||||
state[4] = temp[5];
|
||||
state[8] = temp[10];
|
||||
state[12] = temp[15];
|
||||
// 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 third row 2 steps to the left
|
||||
state[2] = temp[10];
|
||||
state[6] = temp[14];
|
||||
state[10] = temp[2];
|
||||
state[14] = temp[6];
|
||||
|
||||
// Shift fourth row 3 steps to the left
|
||||
state[3] = temp[15];
|
||||
state[7] = temp[3];
|
||||
state[11] = temp[7];
|
||||
state[15] = temp[11];
|
||||
// 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) {
|
||||
U8 temp[16];
|
||||
I64 i;
|
||||
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];
|
||||
|
||||
// Store state in temp
|
||||
for (i = 0; i < 16; i++) {
|
||||
temp[i] = state[i];
|
||||
}
|
||||
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];
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
state[i * 4 + 0] = Mul2[temp[i * 4 + 0]] ^ Mul3[temp[i * 4 + 1]] ^ temp[i * 4 + 2] ^ temp[i * 4 + 3];
|
||||
state[i * 4 + 1] = temp[i * 4 + 0] ^ Mul2[temp[i * 4 + 1]] ^ Mul3[temp[i * 4 + 2]] ^ temp[i * 4 + 3];
|
||||
state[i * 4 + 2] = temp[i * 4 + 0] ^ temp[i * 4 + 1] ^ Mul2[temp[i * 4 + 2]] ^ Mul3[temp[i * 4 + 3]];
|
||||
state[i * 4 + 3] = Mul3[temp[i * 4 + 0]] ^ temp[i * 4 + 1] ^ temp[i * 4 + 2] ^ Mul2[temp[i * 4 + 3]];
|
||||
state[i * 4 + 0] = r0;
|
||||
state[i * 4 + 1] = r1;
|
||||
state[i * 4 + 2] = r2;
|
||||
state[i * 4 + 3] = r3;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -264,7 +273,6 @@ U0 Main() {
|
|||
U8 ctx[176]; // Context (expanded key)
|
||||
|
||||
InitMulTables();
|
||||
|
||||
AES_init_ctx(ctx, key);
|
||||
AES_ECB_encrypt(ctx, buf);
|
||||
|
181
src/Home/Crypto/ChaCha20/ChaCha20.ZC
Normal file
181
src/Home/Crypto/ChaCha20/ChaCha20.ZC
Normal file
|
@ -0,0 +1,181 @@
|
|||
|
||||
// Rotating bits left
|
||||
U32 RotL32(U32 x, I32 n) {
|
||||
return (x << n) | (x >> (32 - n));
|
||||
}
|
||||
|
||||
// Packing bytes into a 32-bit unsigned integer
|
||||
U32 Pack4(U8 *a) {
|
||||
U32 res = 0;
|
||||
res |= a[0](U32) << 0 * 8;
|
||||
res |= a[1](U32) << 1 * 8;
|
||||
res |= a[2](U32) << 2 * 8;
|
||||
res |= a[3](U32) << 3 * 8;
|
||||
return res;
|
||||
}
|
||||
|
||||
// Unpacking a 32-bit unsigned integer into bytes
|
||||
U0 UnPack4(U32 src, U8 *dst) {
|
||||
dst[0] = (src >> 0 * 8) & 0xff;
|
||||
dst[1] = (src >> 1 * 8) & 0xff;
|
||||
dst[2] = (src >> 2 * 8) & 0xff;
|
||||
dst[3] = (src >> 3 * 8) & 0xff;
|
||||
}
|
||||
|
||||
// ChaCha20 context structure
|
||||
class chacha20_context {
|
||||
U32 state[16];
|
||||
U32 keystream32[16];
|
||||
U8 key[32];
|
||||
U8 nonce[12];
|
||||
U64 counter;
|
||||
U32 position;
|
||||
};
|
||||
|
||||
U8 *magic_constant = "expand 32-byte k";
|
||||
// Initializing the ChaCha20 block
|
||||
U0 chacha20_init_block(chacha20_context *ctx, U8 *key, U8 *nonce) {
|
||||
MemCopy(ctx->key, key, 32);
|
||||
MemCopy(ctx->nonce, nonce, 12);
|
||||
|
||||
ctx->state[0] = Pack4(magic_constant + 0 * 4);
|
||||
ctx->state[1] = Pack4(magic_constant + 1 * 4);
|
||||
ctx->state[2] = Pack4(magic_constant + 2 * 4);
|
||||
ctx->state[3] = Pack4(magic_constant + 3 * 4);
|
||||
ctx->state[4] = Pack4(key + 0 * 4);
|
||||
ctx->state[5] = Pack4(key + 1 * 4);
|
||||
ctx->state[6] = Pack4(key + 2 * 4);
|
||||
ctx->state[7] = Pack4(key + 3 * 4);
|
||||
ctx->state[8] = Pack4(key + 4 * 4);
|
||||
ctx->state[9] = Pack4(key + 5 * 4);
|
||||
ctx->state[10] = Pack4(key + 6 * 4);
|
||||
ctx->state[11] = Pack4(key + 7 * 4);
|
||||
// 64 bit counter initialized to zero by default.
|
||||
ctx->state[12] = 0;
|
||||
ctx->state[13] = Pack4(nonce + 0 * 4);
|
||||
ctx->state[14] = Pack4(nonce + 1 * 4);
|
||||
ctx->state[15] = Pack4(nonce + 2 * 4);
|
||||
|
||||
MemCopy(ctx->nonce, nonce, 12);
|
||||
}
|
||||
|
||||
// Setting the counter for the ChaCha20 block
|
||||
U0 chacha20_block_set_counter(chacha20_context *ctx, U64 counter) {
|
||||
ctx->state[12] = counter(U32);
|
||||
ctx->state[13] = Pack4(ctx->nonce + 0 * 4) + (counter >> 32)(U32);
|
||||
}
|
||||
|
||||
U0 CHACHA20_QUARTERROUND(U32 *x, I32 a, I32 b, I32 c, I32 d) {
|
||||
x[a] += x[b]; x[d] = RotL32(x[d] ^ x[a], 16);
|
||||
x[c] += x[d]; x[b] = RotL32(x[b] ^ x[c], 12);
|
||||
x[a] += x[b]; x[d] = RotL32(x[d] ^ x[a], 8);
|
||||
x[c] += x[d]; x[b] = RotL32(x[b] ^ x[c], 7);
|
||||
}
|
||||
|
||||
// Generating the next ChaCha20 block
|
||||
U0 chacha20_block_next(chacha20_context *ctx) {
|
||||
I32 i;
|
||||
for (i = 0; i < 16; i++) ctx->keystream32[i] = ctx->state[i];
|
||||
|
||||
for (i = 0; i < 10; i++) {
|
||||
CHACHA20_QUARTERROUND(ctx->keystream32, 0, 4, 8, 12);
|
||||
CHACHA20_QUARTERROUND(ctx->keystream32, 1, 5, 9, 13);
|
||||
CHACHA20_QUARTERROUND(ctx->keystream32, 2, 6, 10, 14);
|
||||
CHACHA20_QUARTERROUND(ctx->keystream32, 3, 7, 11, 15);
|
||||
CHACHA20_QUARTERROUND(ctx->keystream32, 0, 5, 10, 15);
|
||||
CHACHA20_QUARTERROUND(ctx->keystream32, 1, 6, 11, 12);
|
||||
CHACHA20_QUARTERROUND(ctx->keystream32, 2, 7, 8, 13);
|
||||
CHACHA20_QUARTERROUND(ctx->keystream32, 3, 4, 9, 14);
|
||||
}
|
||||
for (i = 0; i < 16; i++) ctx->keystream32[i] += ctx->state[i];
|
||||
|
||||
U32 *counter = ctx->state + 12;
|
||||
counter[0]++;
|
||||
if (counter[0] == 0) {
|
||||
counter[1]++;
|
||||
if (counter[1] == 0) {
|
||||
// Handle the counter overflow, e.g., print an error message
|
||||
Print("Counter overflow detected\n");
|
||||
// Exit();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Initializing the ChaCha20 context
|
||||
U0 chacha20_init_context(chacha20_context *ctx, U8 *key, U8 *nonce, U64 counter) {
|
||||
MemSet(ctx, 0, sizeof(chacha20_context));
|
||||
|
||||
chacha20_init_block(ctx, key, nonce);
|
||||
chacha20_block_set_counter(ctx, counter);
|
||||
|
||||
ctx->counter = counter;
|
||||
ctx->position = 64;
|
||||
}
|
||||
|
||||
|
||||
// XOR operation for ChaCha20
|
||||
U0 chacha20_xor(chacha20_context *ctx, U8 *bytes, U64 n_bytes) {
|
||||
U8 *keystream8 = ctx->keystream32(U8*);
|
||||
// was U64 for some reason?
|
||||
I64 i;
|
||||
for (i = 0; i < n_bytes; i++) {
|
||||
if (ctx->position >= 64) {
|
||||
chacha20_block_next(ctx);
|
||||
ctx->position = 0;
|
||||
}
|
||||
bytes[i] ^= keystream8[ctx->position++];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Define key and nonce. Ensure they are the correct size (key: 32 bytes, nonce: 12 bytes).
|
||||
U8 key[32] = {
|
||||
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
|
||||
0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
|
||||
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
|
||||
0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F
|
||||
};
|
||||
U8 nonce[12] = {
|
||||
0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x4A,
|
||||
0x00, 0x00, 0x00, 0x00
|
||||
};
|
||||
|
||||
U0 Main() {
|
||||
I64 i;
|
||||
// Define the plaintext message
|
||||
U8 plaintext[16] = "Hello, TempleOS!";
|
||||
U64 plaintext_len = sizeof(plaintext);
|
||||
|
||||
// Allocate space for the ciphertext (same size as plaintext)
|
||||
U8 ciphertext[16];
|
||||
|
||||
// Initialize ChaCha20 context
|
||||
chacha20_context ctx;
|
||||
chacha20_init_context(&ctx, key, nonce, 0); // Counter starts at 0
|
||||
|
||||
// Encrypt the plaintext
|
||||
MemCopy(ciphertext, plaintext, plaintext_len); // Copy plaintext to ciphertext buffer
|
||||
chacha20_xor(&ctx, ciphertext, plaintext_len); // Perform XOR operation
|
||||
|
||||
// Output the encrypted message
|
||||
"Encrypted Message: ";
|
||||
for (i = 0; i < plaintext_len; i++) {
|
||||
"%02X ", ciphertext[i];
|
||||
}
|
||||
"\n";
|
||||
|
||||
// Decrypt the ciphertext (same operation as encryption)
|
||||
chacha20_init_context(&ctx, key, nonce, 0); // Reinitialize context for decryption
|
||||
U8 decrypted[plaintext_len];
|
||||
MemCopy(decrypted, ciphertext, plaintext_len); // Copy ciphertext to decrypted buffer
|
||||
chacha20_xor(&ctx, decrypted, plaintext_len); // Perform XOR operation
|
||||
|
||||
// Output the decrypted message
|
||||
"Decrypted Message: ";
|
||||
for (i = 0; i < plaintext_len; i++) {
|
||||
"%c", decrypted[i];
|
||||
}
|
||||
"\n";
|
||||
}
|
||||
|
||||
Main;
|
Loading…
Reference in a new issue